3 * Copyright 2012 Samsung Electronics Co., Ltd
5 * Licensed under the Flora License, Version 1.1 (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
9 * http://floralicense.org/license/
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.
22 #include "detail-view.h"
23 #include "external-ug.h"
24 #include "list-base.h"
26 static const char *_name = NULL;
28 #define MONTH_CAL_CBAR_H 41
30 #define MONTH_CAL_Y 200
32 #define ANIMATION_TIME 0.2
34 #define INITIAL_FETCH_SIZE 4
35 #define IDLER_FETCH_SIZE 4
40 }focus_in_month_view_type;
43 Evas_Object* container;
45 Evas_Object* month_prev;
46 Evas_Object* month_next;
49 static void __cal_month_view_del(cal_month_view* view)
51 evas_object_del(view->container);
52 evas_object_del(view->month);
53 evas_object_del(view->month_prev);
54 evas_object_del(view->month_next);
61 cal_month_view* vcached_m;
62 cal_month_view* vcached_w;
63 cal_month_view* vcached_l;
69 Evas_Coord_Rectangle rect;
70 Evas_Coord_Rectangle oringinal_size;
72 focus_in_month_view_type calendar_focus_view;
74 Eina_List *event_list;
79 Evas_Coord_Point down1, down2;
83 Evas_Coord_Point move1, move2;
92 Evas_Coord_Rectangle pos_from;
93 Evas_Coord_Rectangle pos_to;
100 int calendar_slide_last_pos;
103 extern void cal_month_calendar_update_view(Evas_Object *ly);
105 static void __cal_month_mouse_move_event_callback(void *data, Evas *e, Evas_Object *ly, void *ei);
106 static void __cal_month_update_genlist(cal_month_data *p);
107 static void __cal_month_changed_callback(void *data, Evas_Object *obj, const char *e, const char *src);
108 static void __cal_month_set_title_text(struct appdata *ad, const struct tm* tm);
110 static inline void __cal_month_stop_animation(cal_month_data *p)
113 ecore_animator_del(p->ani);
118 static void __cal_month_text_refresh_callback(void *data)
122 c_retm_if(!data, "data is null");
123 cal_month_data *p = data;
125 cal_main_update_title_text(p->ad);
126 cal_month_calendar_set_wday_text(p->vcur->month, p->ad->wday_start);
127 elm_object_text_set(p->ad->new_event_button, S_("IDS_COM_BODY_CREATE"));
129 elm_genlist_realized_items_update(p->list);
132 static void __cal_month_delete_layout(void *data, Evas *e, Evas_Object *obj, void *ei)
136 c_retm_if(!data, "data is null");
137 c_retm_if(!e, "e is null");
139 cal_month_data *p = data;
141 _calendar_free_record_list(&p->event_list);
144 if (p->vcached_m && p->vcached_m != p->vcur) {
145 __cal_month_view_del(p->vcached_m);
149 if (p->vcached_w && p->vcached_w != p->vcur) {
150 __cal_month_view_del(p->vcached_w);
154 if (p->vcached_l && p->vcached_l != p->vcur) {
155 __cal_month_view_del(p->vcached_l);
162 __cal_month_stop_animation(p);
165 ecore_idler_del(p->idler);
168 evas_object_del(p->popup);
170 cal_lang_manager_remove_callback(__cal_month_text_refresh_callback, p);
176 static void __cal_month_resize_view(void *data, Evas *e, Evas_Object *ly, void *ei)
178 cal_month_data *p = data;
180 cal_util_get_geometry(&p->rect, p->vcur->month);
183 static void __cal_month_get_events(cal_month_data *p)
185 struct tm tm_start = p->ad->base_tm;
186 tm_start.tm_hour = 0;
190 struct tm tm_end = tm_start;
195 p->event_list = _calendar_get_all_instance_list(&tm_start, &tm_end);
197 Eina_List *todo_list = _calendar_get_due_date_task_list(&tm_start, &tm_end, p->ad->is_display_complete_todo, _CALENDAR_TASK_SORT_TYPE_DUEDATE_ASC);
198 p->event_list = eina_list_merge(p->event_list, todo_list);
201 static void __cal_month_update_genlist(cal_month_data *p)
205 c_retm_if(!p, "p is null");
207 _calendar_free_record_list(&p->event_list);
209 __cal_month_get_events(p);
212 p->list = cal_list_base_create(p->ad, p->vcur->container, "list/sw", true, NULL, NULL);
214 elm_genlist_clear(cal_list_base_get_genlist_p(p->list));
219 calendar_record_h record = NULL;
221 EINA_LIST_FOREACH(p->event_list, l, record) {
223 cal_list_base_add_item(p->list, record, false);
229 static Evas_Object* __cal_month_create_month_d(cal_month_view* v, cal_month_data *p, int d)
234 struct appdata *ad = p->ad;
235 c_retv_if(!ad, NULL);
237 struct tm base_tm_bak = ad->base_tm;
239 time_t r = cal_util_update_tm_month(&ad->base_tm, d);
240 c_retv_if(r < 0, NULL);
242 Evas_Object *calendar = cal_month_calendar_create_view(ad, v->container, EINA_TRUE);
244 ad->base_tm = base_tm_bak;
249 static void __cal_month_move_prev_month_calendar(cal_month_data *p, Evas_Coord x)
251 if (p->vcur->month_prev == NULL) {
252 p->vcur->month_prev = __cal_month_create_month_d(p->vcur, p, -1);
253 if (!p->vcur->month_prev ) {
254 Evas_Coord dx = p->move1.x - p->down1.x;
256 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->vcur->month), "elm,edge,left", "elm");
260 elm_object_part_content_set(p->vcur->container, "cal/sw/left", p->vcur->month_prev);
263 if(0 > p->oringinal_size.x)
265 evas_object_move(p->vcur->month_prev, x, p->rect.y);
269 evas_object_move(p->vcur->month_prev, x, p->oringinal_size.y);
274 static void __cal_month_move_next_month_calendar(cal_month_data *p, Evas_Coord x)
276 if (p->vcur->month_next == NULL) {
277 p->vcur->month_next = __cal_month_create_month_d(p->vcur, p, 1);
278 if (!p->vcur->month_next) {
279 Evas_Coord dx = p->move1.x - p->down1.x;
281 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->vcur->month), "elm,edge,right", "elm");
285 elm_object_part_content_set(p->vcur->container, "cal/sw/right", p->vcur->month_next);
288 if(0 > p->oringinal_size.x)
290 evas_object_move(p->vcur->month_next, x, p->rect.y);
294 evas_object_move(p->vcur->month_next, x, p->oringinal_size.y);
298 static void __cal_month_set_title_text(struct appdata *ad, const struct tm* tm)
301 c_ret_if(!ad->main_navi_item);
302 Elm_Object_Item* title = ad->main_navi_item;
303 cal_util_set_item_time_text(title, "default", CAL_UTIL_DATE_FORMAT_6, NULL, tm);
306 static void __cal_month_update_title_text(cal_month_data* p, int dx)
308 struct appdata* ad = p->ad;
309 c_retm_if(!ad, "ad is null");
311 if ((dx > 0 ? dx : -dx) > (p->rect.w / 2)) {
313 if (p->calendar_slide_last_pos <= 0) {
314 struct tm t = ad->base_tm;
315 cal_util_update_tm_month(&t, -1);
316 __cal_month_set_title_text(ad, &t);
317 p->calendar_slide_last_pos = 1;
320 if (p->calendar_slide_last_pos >= 0) {
321 struct tm t = ad->base_tm;
322 cal_util_update_tm_month(&t, 1);
323 __cal_month_set_title_text(ad, &t);
324 p->calendar_slide_last_pos = -1;
328 if (p->calendar_slide_last_pos != 0) {
329 __cal_month_set_title_text(ad, &ad->base_tm);
330 p->calendar_slide_last_pos = 0;
335 static void __cal_month_move_month_calendar(cal_month_data *p)
339 Evas_Coord th = elm_config_finger_size_get();
341 Evas_Coord dx = p->move1.x - p->down1.x;
342 if (!p->single_moved && dx < th && dx > -th)
345 if (!p->single_moved)
346 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->vcur->month), "moved", "prog");
350 __cal_month_update_title_text(p, dx);
353 if (p->oringinal_size.x < 0) {
356 __cal_month_move_prev_month_calendar(p, x - p->rect.w);
357 __cal_month_move_next_month_calendar(p, x + p->rect.w);
359 if (p->vcur->month_prev) {
360 evas_object_move(p->vcur->month, x, p->rect.y);
363 if (p->vcur->month_next) {
364 evas_object_move(p->vcur->month, x, p->rect.y);
370 x = p->oringinal_size.x + dx;
372 __cal_month_move_prev_month_calendar(p, x - p->oringinal_size.w);
373 __cal_month_move_next_month_calendar(p, x + p->oringinal_size.w);
375 if (p->vcur->month_prev) {
376 evas_object_move(p->vcur->month, x, p->oringinal_size.y);
379 if (p->vcur->month_next) {
380 evas_object_move(p->vcur->month, x, p->oringinal_size.y);
386 static inline void __cal_month_move_objects(cal_month_data *p, Evas_Coord dx)
393 struct appdata *ad = p->ad;
394 c_retm_if(!ad, "ad is null");
402 r = cal_util_update_tm_month(&t, -1);
408 r = cal_util_update_tm_month(&t, 1);
412 Evas_Coord x = p->pos_from.x + dx;
414 __cal_month_move_prev_month_calendar(p, x - p->rect.w);
415 __cal_month_move_next_month_calendar(p, x + p->rect.w);
418 if (p->vcur->month_prev) {
419 evas_object_move(p->vcur->month, x, p->rect.y);
422 if (p->vcur->month_next) {
423 evas_object_move(p->vcur->month, x, p->rect.y);
428 static void __cal_month_list_icon_clicked_callback(void *data, Evas_Object *obj, const char *e, const char *src);
429 static void __cal_month_mouse_down_event_callback(void *data, Evas *e, Evas_Object *ly, void *ei);
430 static void __cal_month_mouse_up_event_callback(void *data, Evas *e, Evas_Object *ly, void *ei);
432 static cal_month_view* __cal_month_create_layout(cal_month_data* p)
434 cal_month_view* v = (cal_month_view*)calloc(1, sizeof(cal_month_view));
439 layout = cal_util_add_layout(p->ad->naviframe, p->name);
446 v->container = layout;
448 evas_object_data_set(layout, "priv", p);
450 evas_object_hide(layout);
452 evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_DOWN, __cal_month_mouse_down_event_callback, p);
453 evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_UP, __cal_month_mouse_up_event_callback, p);
454 evas_object_event_callback_add(layout, EVAS_CALLBACK_RESIZE, __cal_month_resize_view, p);
456 v->month = cal_month_calendar_create_view(p->ad, layout, EINA_TRUE);
457 v->month_next = __cal_month_create_month_d(v, p, 1);
458 v->month_prev = __cal_month_create_month_d(v, p, -1);
460 elm_object_part_content_set(layout, "cal/sw", v->month);
461 elm_object_part_content_set(layout, "cal/sw/left", v->month_prev);
462 elm_object_part_content_set(layout, "cal/sw/right", v->month_next);
464 // cal_month_calendar_update_select(p->vcur->month);
466 // cal_month_update_view(layout);
468 // cal_month_calendar_update_view(v->month);
469 // cal_month_calendar_update_view(v->month_next);
470 // cal_month_calendar_update_view(v->month_prev);
472 // __cal_month_update_genlist(p);
477 static void __cal_month_create_missing_parts(cal_month_view* v, cal_month_data* p)
479 if (v->month == NULL)
480 v->month = cal_month_calendar_create_view(p->ad, v->container, EINA_TRUE);
482 if (v->month_next == NULL)
483 v->month_next = __cal_month_create_month_d(v, p, 1);
485 if (v->month_prev == NULL)
486 v->month_prev = __cal_month_create_month_d(v, p, -1);
488 elm_object_part_content_set(v->container, "cal/sw", v->month);
489 elm_object_part_content_set(v->container, "cal/sw/left", v->month_prev);
490 elm_object_part_content_set(v->container, "cal/sw/right", v->month_next);
493 static void __cal_month_switch_mode(cal_month_data* p)
498 evas_object_event_callback_del(p->vcur->month, EVAS_CALLBACK_MOUSE_MOVE, __cal_month_mouse_move_event_callback);
499 edje_object_signal_callback_del(CAL_UTIL_GET_EDJ_DATA(p->vcur->month), "changed", "prog", __cal_month_changed_callback);
500 Evas_Object *layout = elm_object_part_content_unset(p->ad->main, "cont");
501 evas_object_hide(p->vcur->month);
502 evas_object_hide(p->vcur->month_next);
503 evas_object_hide(p->vcur->month_prev);
504 evas_object_event_callback_del(layout, EVAS_CALLBACK_DEL, __cal_month_delete_layout);
505 evas_object_hide(layout);
508 if (p->ad->is_landscape_mode) {
509 p->name = _name = "main/month/weekly/l";
510 if (p->vcached_l == NULL)
511 p->vcached_l = __cal_month_create_layout(p);
513 __cal_month_create_missing_parts(p->vcached_l, p);
514 p->vcur = p->vcached_l;
516 if (p->ad->daily_events_mode) {
517 p->name = _name = "main/month/weekly";
518 if (p->vcached_w == NULL)
519 p->vcached_w = __cal_month_create_layout(p);
521 __cal_month_create_missing_parts(p->vcached_w, p);
522 p->vcur = p->vcached_w;
524 p->name = _name = "main/month";
525 if (p->vcached_m == NULL)
526 p->vcached_m = __cal_month_create_layout(p);
528 __cal_month_create_missing_parts(p->vcached_m, p);
529 p->vcur = p->vcached_m;
533 evas_object_event_callback_add(p->vcur->container, EVAS_CALLBACK_DEL, __cal_month_delete_layout, p);
535 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(p->vcur->container), "set,default");
537 if (!p->ad->daily_events_mode)
538 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(p->vcur->container), "go,line%d", cal_month_calendar_get_weekline(p->vcur->month));
540 evas_object_event_callback_add(p->vcur->month, EVAS_CALLBACK_MOUSE_MOVE, __cal_month_mouse_move_event_callback, p);
541 edje_object_signal_callback_add(CAL_UTIL_GET_EDJ_DATA(p->vcur->month), "changed", "prog", __cal_month_changed_callback, p);
543 evas_object_show(p->vcur->container);
544 elm_object_part_content_set(p->ad->main, "cont", p->vcur->container);
545 cal_main_set_main_content(p->ad, p->vcur->container);
546 evas_object_show(p->vcur->month);
549 static void __cal_month_shift(cal_month_view* v, cal_month_data *p, int d)
554 elm_object_part_content_unset(v->container, "cal/sw");
555 elm_object_part_content_unset(v->container, "cal/sw/left");
556 elm_object_part_content_unset(v->container, "cal/sw/right");
560 evas_object_del(v->month_prev);
561 v->month_prev = v->month;
562 v->month = v->month_next;
564 v->month_next = __cal_month_create_month_d(v, p, 1);
566 v->month_next = NULL;
570 evas_object_del(v->month_next);
571 v->month_next = v->month;
572 v->month = v->month_prev;
574 v->month_prev = __cal_month_create_month_d(v, p, -1);
576 v->month_prev = NULL;
579 elm_object_part_content_set(v->container, "cal/sw", v->month);
580 elm_object_part_content_set(v->container, "cal/sw/left", v->month_prev);
581 elm_object_part_content_set(v->container, "cal/sw/right", v->month_next);
584 static inline int __cal_month_update_month_view(cal_month_data *p, int d)
590 r = cal_util_update_tm_month(&p->ad->base_tm, d);
594 cal_month_view* vcur = p->vcur;
596 edje_object_signal_callback_del(CAL_UTIL_GET_EDJ_DATA(vcur->month), "changed", "prog", __cal_month_changed_callback);
597 evas_object_event_callback_del(vcur->month, EVAS_CALLBACK_MOUSE_MOVE, __cal_month_mouse_move_event_callback);
599 __cal_month_shift(p->vcached_m, p, d);
600 __cal_month_shift(p->vcached_w, p, d);
601 __cal_month_shift(p->vcached_l, p, d);
603 cal_month_calendar_update_select(vcur->month);
605 if (!p->ad->daily_events_mode)
606 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(p->vcur->container), "go,line%d", cal_month_calendar_get_weekline(p->vcur->month));
608 evas_object_show(vcur->container);
610 evas_object_event_callback_add(vcur->month, EVAS_CALLBACK_MOUSE_MOVE, __cal_month_mouse_move_event_callback, p);
611 edje_object_signal_callback_add(CAL_UTIL_GET_EDJ_DATA(p->vcur->month), "changed", "prog", __cal_month_changed_callback, p);
613 __cal_month_update_genlist(p);
619 static Eina_Bool __cal_month_animation(void *data)
621 cal_month_data *p = data;
625 elapsed_t = ecore_time_get() - p->ani_start;
626 if (elapsed_t > ANIMATION_TIME)
627 elapsed_t = ANIMATION_TIME;
629 dx = (p->pos_to.x - p->pos_from.x) * cal_util_nsin(elapsed_t / ANIMATION_TIME);
630 __cal_month_move_objects(p, dx);
632 if (elapsed_t == ANIMATION_TIME || dx == 0)
636 ecore_animator_del(p->ani);
642 __cal_month_update_month_view(p,p->d);
645 p->calendar_slide_last_pos = 0;
647 return ECORE_CALLBACK_CANCEL;
650 return ECORE_CALLBACK_RENEW;
653 static inline void __cal_month_start_animation(cal_month_data *p)
655 if (p->pos_from.x == p->pos_to.x)
659 p->ani = ecore_animator_add(__cal_month_animation, p);
660 p->ani_start = ecore_time_get();
663 static void __cal_month_mouse_up_event_callback(void *data, Evas *e, Evas_Object *ly, void *ei)
666 cal_month_data *p = data;
669 struct appdata* ad = p->ad;
671 Evas_Event_Mouse_Up *ev = ei;
673 p->down_is_called = 0;
675 if (p->single_flicked) {
676 int dy = p->down1.y - ev->canvas.y;
677 p->single_flicked = 0;
680 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(p->vcur->container), "expand,up");
682 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(p->vcur->container), "expand,down");
685 } else if (p->single_moved) {
686 int dx = p->down1.x - ev->canvas.x;
696 cal_util_get_geometry(&p->pos_from,p->vcur->month);
698 if (dx > cal_util_get_flick_distance_threshold())
703 p->pos_to.x = p->ad->win_w;
704 p->pos_to.y = p->pos_from.y;
705 p->pos_to.w = p->pos_from.w;
706 p->pos_to.h = p->pos_from.h;
711 p->pos_to.x = -(p->ad->win_w);
712 p->pos_to.y = p->pos_from.y;
713 p->pos_to.w = p->pos_from.w;
714 p->pos_to.h = p->pos_from.h;
716 __cal_month_start_animation(p);
722 p->pos_to.y = p->pos_from.y;
723 p->pos_to.w = p->pos_from.w;
724 p->pos_to.h = p->pos_from.h;
725 __cal_month_start_animation(p);
733 static void __cal_month_mouse_down_event_callback(void *data, Evas *e, Evas_Object *ly, void *ei)
735 cal_month_data *p = data;
736 Evas_Event_Mouse_Down *ev = ei;
738 p->down1.x = p->move1.x = ev->canvas.x;
739 p->down1.y = p->move1.y = ev->canvas.y;
741 p->down_is_called = 1;
742 p->multi_touched = 0;
744 cal_util_get_geometry(&p->oringinal_size,p->vcur->month);
747 static void __cal_month_mouse_move_event_callback(void *data, Evas *e, Evas_Object *ly, void *ei)
749 c_retm_if(!data, "data is null");
750 c_retm_if(!ei, "ei is null");
752 cal_month_data *p = data;
753 Evas_Event_Mouse_Move *ev = ei;
754 Evas_Coord th = elm_config_finger_size_get();
755 int y_distance = ev->cur.canvas.y - p->down1.y;
757 if (th < abs(y_distance) && !p->ad->daily_events_mode) {
758 struct appdata* ad = p->ad;
761 if (!p->multi_touched && !p->single_moved && !p->single_flicked) {
762 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->vcur->month), "moved", "prog");
763 p->single_flicked = 1;
767 if (th < abs(ev->cur.canvas.x - p->down1.x)) {
768 struct appdata* ad = p->ad;
773 if (0 == p->down_is_called)
776 p->move1.x = ev->cur.canvas.x;
777 p->move1.y = ev->cur.canvas.y;
779 if (!p->multi_touched && !p->single_flicked)
780 __cal_month_move_month_calendar(p);
783 static void __cal_month_changed_callback(void *data, Evas_Object *obj, const char *e, const char *src)
785 __cal_month_update_genlist(data);
788 Evas_Object* cal_month_create_view(struct appdata *ad, Evas_Object *main)
792 c_retvm_if(!ad, NULL, "ad is null");
793 c_retvm_if(!main, NULL, "main is null");
798 Evas_Object *list_bg;
801 p = calloc(1, sizeof(cal_month_data));
802 c_retv_if (!p, NULL);
804 r = vconf_get_int(CAL_VCONFKEY_WEEK_NMUBER_ON_OFF, (int *)&ad->is_display_weeknumber);
806 ERR("vconf_get_int(CAL_VCONFKEY_WEEK_NMUBER_ON_OFF, (int *)&ad->is_display_weeknumber) is failed");
811 r = vconf_get_int(CAL_VCONFKEY_COMPLETE_TODO_ON_OFF, (int *)&ad->is_display_complete_todo);
813 ERR("vconf_get_int(CAL_VCONFKEY_COMPLETE_TODO_ON_OFF, (int *)&p->is_display_complete_todo) is failed");
820 ad->tapbar_focus_view = CV_MONTH;
823 p->oringinal_size.x = -1;
824 p->oringinal_size.y = -1;
825 p->oringinal_size.w = -1;
826 p->oringinal_size.h = -1;
828 __cal_month_switch_mode(p);
830 list_bg = cal_util_add_bg(p->vcur->container, EINA_FALSE);
833 ERR("cal_util_add_bg(ly, EINA_FALSE) is failed");
834 evas_object_del(p->vcur->container);
839 elm_object_part_content_set(p->vcur->container, "list/base", list_bg);
841 cal_lang_manager_add_callback(__cal_month_text_refresh_callback, p)
845 return p->vcur->container;
848 void cal_month_update_view(Evas_Object *ly)
852 c_retm_if(!ly, "ly is null");
857 p = CAL_UTIL_GET_PRIV_DATA(ly);
858 if (!p || CAL_STRCMP(p->name, _name)) {
859 ERR("update month view: Invalid object");
864 c_retm_if(!ad, "ad is null");
866 if (p->vcached_l != NULL && p->vcur != p->vcached_l) {
867 __cal_month_view_del(p->vcached_l);
871 if (p->vcached_m != NULL && p->vcur != p->vcached_m) {
872 __cal_month_view_del(p->vcached_m);
876 if (p->vcached_w != NULL && p->vcur != p->vcached_w) {
877 __cal_month_view_del(p->vcached_w);
881 cal_month_calendar_update_view(p->vcur->month);
883 if (!p->ad->daily_events_mode)
884 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(p->vcur->container), "go,line%d", cal_month_calendar_get_weekline(p->vcur->month));
886 __cal_month_update_genlist(p);
888 cal_util_delete_evas_object(&p->vcur->month_prev);
889 cal_util_delete_evas_object(&p->vcur->month_next);