3 * Copyright 2012 Samsung Electronics Co., Ltd
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
9 * http://www.tizenopensource.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.
21 #include <vconf-keys.h>
23 #include "timeblock.h"
25 #define CAL_TIMEBLOCK_CONTENT_HEIGHT 16
26 #define CAL_TIMEBLOCK_MIN_HEIGHT 16
27 #define CAL_TIMEBLOCK_NORMAL_HEIGHT 158
28 #define CAL_TIMEBLOCK_EXPAND_HEIGHT 520
29 #define CAL_TIMEBLOCK_TEXT_HEIGHT 30
30 #define CAL_TIMEBLOCK_LONG_PRESS_TIME 0.5
31 #define CAL_TIMEBLOCK_EVENT_BLOCK_MAX 8
33 static void __cal_time_block_restack_time_block(struct timeblock *tb);
34 extern void cal_day_update_expand(Evas_Object *ly, int x);
36 void cal_time_block_show_current_time_line(struct timeblock *tb, int hour)
39 struct timeblock_slice *t;
44 if(0 > hour || 23 < hour)
47 for(i = 0; i < sizeof(tb->tbs)/sizeof(tb->tbs[0]); i++)
50 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(t->ly), "hide,line", "prog");
51 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(t->ly), "hide,img", "prog");
54 if(NULL != tb->tbs[hour].ly)
56 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(tb->tbs[hour].ly), "show,line", "prog");
57 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(tb->tbs[hour].ly), "show,img", "prog");
61 void cal_time_block_hide_current_time_line(struct timeblock *tb)
64 struct timeblock_slice *t;
69 for(i = 0; i < sizeof(tb->tbs)/sizeof(tb->tbs[0]); i++)
72 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(t->ly), "hide,line", "prog");
73 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(t->ly), "hide,img", "prog");
77 static int __cal_time_block_sort_ev(const void *d1, const void *d2)
79 const struct timeblock_event *t1 = d1;
80 const struct timeblock_event *t2 = d2;
87 return t1->sz < t2->sz ? 1 : -1;
90 static void __cal_time_block_delete_event_block_slice_overlap(struct timeblock *tb)
94 struct eventblock_overlap *ebv = NULL;
97 EINA_LIST_FOREACH(tb->ebs_list, l, ebv) {
102 tb->ebs_list = eina_list_free(tb->ebs_list);
105 static void _cal_time_block_clear_start_index(struct timeblock *tb)
108 struct eventblock_slice *eb = NULL;
113 for(i = 0; i<sizeof(tb->ebs)/sizeof(tb->ebs[0]); i++)
120 static void __cal_time_block_set_start_index(struct timeblock *tb)
127 struct eventblock_slice *eb = NULL;
128 struct eventblock_slice *eb_tmp = NULL;
130 const struct timeblock_event *ev = NULL;
135 _cal_time_block_clear_start_index(tb);
136 for(i = 0; i<sizeof(tb->ebs)/sizeof(tb->ebs[0]); i++)
142 EINA_LIST_FOREACH(eb->list, l, ev)
146 e = ev->idx + ev->sz;
147 for(j = ev->idx; (j<e && j<sizeof(tb->ebs)/sizeof(tb->ebs[0])); j++)
149 eb_tmp = &tb->ebs[j];
153 eb_tmp->start_index = eb->start_index + 1;
155 eb_tmp->start_index = eb_tmp->start_index + 1;
157 sz = eina_list_count(eb_tmp->list);
158 eb_tmp->real_sz = eb_tmp->start_index + sz;
168 static void __cal_time_block_set_event_block_slice_overlap_ranged(struct timeblock *tb)
172 struct eventblock_slice *eb = NULL;
173 struct eventblock_overlap *ebv = NULL;
179 __cal_time_block_set_start_index(tb);
180 nebs = sizeof(tb->ebs)/sizeof(tb->ebs[0]);
181 __cal_time_block_delete_event_block_slice_overlap(tb);
186 if(0 == eb->start_index)
193 CAL_CALLOC(ebv, 1, struct eventblock_overlap);
200 ebv->size = eb->real_sz;
204 tb->ebs_list = eina_list_append(tb->ebs_list, ebv);
206 for(j = i+1; j < nebs; j++)
210 if((j == nebs-1) && (0 != eb->start_index))
212 if(eb->real_sz > ebv->size)
214 ebv->size = eb->real_sz;
217 tb->ebs_list = eina_list_append(tb->ebs_list, ebv);
219 else if(0 == eb->start_index)
221 ebv->end_idx = j - 1;
222 tb->ebs_list = eina_list_append(tb->ebs_list, ebv);
228 if(eb->real_sz > ebv->size)
230 ebv->size = eb->real_sz;
244 static void __cal_time_block_move_event(struct timeblock_event *ev, Evas_Coord_Rectangle *base,
245 int idx, Evas_Coord w)
247 c_retm_if(!ev, "ev is null");
248 c_retm_if(!ev->tb, "ev->tb is null");
249 c_retm_if(!ev->ly, "ev->ly is null");
251 if (ev->tb->long_pressed_event == ev)
254 evas_object_move(ev->ly, base->x + (idx * w), base->y);
255 evas_object_resize(ev->ly, w, base->h * ev->sz);
258 static void __cal_time_block_move_event_block_slice(struct timeblock *tb)
260 c_retm_if(!tb, "tb is null");
262 struct eventblock_overlap *ebv = NULL;
265 struct eventblock_slice *eb = NULL;
266 Evas_Coord_Rectangle base = {0};
267 struct timeblock_event *ev = NULL;
272 __cal_time_block_set_event_block_slice_overlap_ranged(tb);
274 EINA_LIST_FOREACH(tb->ebs_list, l, ebv) {
277 for ( i = ebv->start_idx; i <= ebv->end_idx; i++) {
280 cal_util_get_geometry(&base, eb->base);
281 if (ebv->size > CAL_TIMEBLOCK_EVENT_BLOCK_MAX) {
282 width = base.w / CAL_TIMEBLOCK_EVENT_BLOCK_MAX;
284 width = base.w / ebv->size;
287 count = eb->start_index;
289 EINA_LIST_FOREACH(eb->list, l2, ev) {
291 if(count < CAL_TIMEBLOCK_EVENT_BLOCK_MAX-1) {
292 __cal_time_block_move_event(ev, &base, count, width);
294 __cal_time_block_move_event(ev, &base, count, 0);
305 void cal_time_block_move(struct timeblock *time_block, Evas_Coord x, Evas_Coord y)
307 c_retm_if(!time_block, "time_block is null");
310 struct timeblock_slice *t;
315 for (i = 0; i < sizeof(time_block->tbs)/sizeof(time_block->tbs[0]); i++) {
316 t = &time_block->tbs[i];
320 evas_object_move(t->ly, x, y);
327 __cal_time_block_move_event_block_slice(time_block);
330 static void __cal_time_block_resize_time_block(struct timeblock *time_block)
336 for (i = 0; i < sizeof(time_block->tbs)/sizeof(time_block->tbs[0]); i++) {
337 struct timeblock_slice *t = &time_block->tbs[i];
342 if (t->h > CAL_TIMEBLOCK_TEXT_HEIGHT) {
344 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(t->ly), "show,text", "prog");
345 t->hide_text = EINA_FALSE;
350 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(t->ly), "hide,text", "prog");
351 t->hide_text = EINA_TRUE;
355 evas_object_resize(t->ly, time_block->w, t->h);
362 static inline void __cal_time_block_set_size(struct timeblock *tb, Evas_Coord h)
365 c_retm_if(!tb, "tb is null");
366 c_retm_if(!tb->ad, "tb->ad is null");
367 struct appdata *ad = tb->ad;
369 if (tb->expand_height <= h)
370 h = tb->expand_height;
372 for (i = 0; i < sizeof(tb->tbs)/sizeof(tb->tbs[0]); i++)
374 struct timeblock_slice *t = &tb->tbs[i];
379 if (tb->normal_height < h)
382 t->h = tb->normal_height;
388 static int __cal_time_block_find_time_block(struct timeblock *tb, Evas_Coord y)
391 struct timeblock_slice *t;
393 for (i = 1; i < sizeof(tb->tbs)/sizeof(tb->tbs[0]); i++) {
403 static void __cal_time_block_rearrange_time_block_after(struct timeblock *tb, int idx)
406 struct timeblock_slice *prev;
407 struct timeblock_slice *t;
409 for (i = idx + 1; i < sizeof(tb->tbs)/sizeof(tb->tbs[0]); i++) {
411 prev = &tb->tbs[i - 1];
413 t->y = prev->y + prev->h;
414 evas_object_move(t->ly, t->x, t->y);
418 static inline void __cal_time_block_rearrange_time_block(struct timeblock *tb, int idx)
420 struct timeblock_slice *t;
421 struct timeblock_slice *next;
424 __cal_time_block_rearrange_time_block_after(tb, idx);
426 for (i = idx - 1; i >= 0; i--) {
428 next = &tb->tbs[i + 1];
430 t->y = next->y - t->h;
431 evas_object_move(t->ly, t->x, t->y);
434 tb->y = tb->tbs[0].y;
437 void cal_time_block_resize(struct timeblock *tb, Evas_Coord y, Evas_Coord h)
444 idx = __cal_time_block_find_time_block(tb, y);
446 __cal_time_block_set_size(tb, h);
447 __cal_time_block_resize_time_block(tb);
448 __cal_time_block_rearrange_time_block(tb, idx);
449 __cal_time_block_move_event_block_slice(tb);
452 static inline int __cal_time_block_get_color(struct timeblock *tb)
457 tb->color = (tb->color + 1) & 0x3;
462 static Evas_Object* __cal_time_block_add_event_layout(struct timeblock *tb, const char *text)
466 ly = cal_util_add_layout(tb->parent, "main/day/tb/event");
469 evas_object_size_hint_align_set(ly, EVAS_HINT_FILL, EVAS_HINT_FILL);
472 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "text", text);
474 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "bg,color%d", __cal_time_block_get_color(tb));
476 evas_object_clip_set(ly, (Evas_Object*)tb->clip);
481 static void __cal_time_event_mouse_down_callback(void *data, Evas *e, Evas_Object *ly, void *ei)
485 c_retm_if(!data, "data is null");
486 c_retm_if(!ei, "ei is null");
488 Evas_Event_Mouse_Down *ev = ei;
489 struct timeblock_event *event = data;
491 event->mouse_down_y = ev->canvas.y;
494 static struct timeblock_event* __cal_time_block_add_event(struct timeblock *time_block, int cid, int hh, int sz, const char *text, cal_struct *cs)
496 CAL_ASSERT(time_block);
499 struct timeblock_event *e;
502 CAL_CALLOC(e, 1, struct timeblock_event);
504 ly = __cal_time_block_add_event_layout(time_block, text);
514 evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_DOWN, __cal_time_event_mouse_down_callback, e);
519 static int __cal_time_block_get_event_block_index(struct timeblock_event *ev)
521 c_retvm_if(!ev, -1, "ev is null");
522 c_retvm_if(!ev->tb, -1, "ev->tb is null");
524 struct timeblock *tb = ev->tb;
526 Evas_Coord_Rectangle r;
527 Evas_Coord event_y, ebs_y;
529 cal_util_get_geometry(&r, ev->ly);
532 for (i = 0; i < sizeof(tb->ebs)/sizeof(tb->ebs[0]); i++) {
534 cal_util_get_geometry(&r, tb->ebs[i].base);
536 if (event_y <= r.y) {
540 cal_util_get_geometry(&r, tb->ebs[i - 1].base);
542 if (event_y - r.y < ebs_y - event_y)
553 static void __cal_time_block_event_callback(void *data, Evas_Object *obj, const char *e, const char *s)
557 c_retm_if(!data, "data is null");
559 struct timeblock_event *ev = data;
560 struct timeblock *tb = ev->tb;
561 c_retm_if(!tb, "tb is null");
566 if (!CAL_STRCMP(e, "dn")) {
569 edje_object_signal_emit(obj, "select", "prog");
574 if (!CAL_STRCMP(e, "up")) {
578 tb->cb(tb->cb_d, tb, EVENT_CLICKED, ev);
582 edje_object_signal_emit(obj, "unselect", "prog");
589 static int __cal_time_block_insert_event(struct timeblock *time_block, struct timeblock_event *ev)
591 CAL_ASSERT(time_block);
597 struct eventblock_slice *eb;
600 e = (ev->idx + ev->sz + 1) >> 1;
602 for (i = idx; i < e && i < sizeof(time_block->tbs)/sizeof(time_block->tbs[0]); i++)
603 time_block->tbs[i].cnt++;
605 eb = &time_block->ebs[ev->idx];
606 eb->list = eina_list_sorted_insert(eb->list, __cal_time_block_sort_ev, ev);
607 edje_object_signal_callback_add(CAL_UTIL_GET_EDJ_DATA(ev->ly), "*", "edj", __cal_time_block_event_callback, ev);
612 static struct timeblock_event* __cal_time_block_find_event(struct timeblock *time_block, int cid)
614 CAL_ASSERT(time_block);
616 struct eventblock_slice *eb;
617 struct timeblock_event *ev;
620 for (i = 0; i < sizeof(time_block->ebs)/sizeof(time_block->ebs[0]); i++)
622 eb = &time_block->ebs[i];
624 EINA_LIST_FOREACH(eb->list, l, ev)
626 if (ev && ev->cid == cid)
634 static void __cal_time_block_restack_time_block(struct timeblock *tb)
638 struct eventblock_slice *eb;
639 struct timeblock_event *ev;
643 for (i = 0; i < sizeof(tb->ebs)/sizeof(tb->ebs[0]); i++)
647 EINA_LIST_FOREACH(eb->list, l, ev)
649 if (prev && NULL != ev) {
650 evas_object_stack_above(ev->ly, prev);
659 void cal_time_block_add_event(struct timeblock *time_block, int cid, int hh, int sz, const char *text, cal_struct *cs)
661 CAL_ASSERT(time_block);
664 struct timeblock_event *e;
667 e = __cal_time_block_find_event(time_block, cid);
675 e = __cal_time_block_add_event(time_block, cid, hh, sz, text, cs);
678 idx = __cal_time_block_insert_event(time_block, e);
680 __cal_time_block_restack_time_block(time_block);
681 __cal_time_block_rearrange_time_block_after(time_block, idx);
682 __cal_time_block_move_event_block_slice(time_block);
685 void cal_time_block_get_geometry(struct timeblock *time_block, Evas_Coord_Rectangle *r)
687 CAL_ASSERT(time_block);
690 r->x = time_block->x;
691 r->y = time_block->y;
692 r->w = time_block->w;
693 r->h = time_block->h;
696 static void __cal_time_block_time_block_callback(void *data, Evas_Object *obj, const char *e, const char *s)
698 struct timeblock_slice *t = data;
699 struct timeblock *tb = t->tb;
704 if (!CAL_STRCMP(e, "dn")) {
705 if (!tb->dn && t->h == tb->normal_height ) {
707 edje_object_signal_emit(obj, "select", "prog");
712 if (!CAL_STRCMP(e, "up")) {
715 tb->cb(tb->cb_d, tb, TIMEBLOCK_CLICKED, (void *)t->idx);
717 edje_object_signal_emit(obj, "unselect", "prog");
723 static void __cal_time_block_add_time_block(struct timeblock *time_block)
726 struct timeblock_slice *t;
727 struct eventblock_slice *e;
734 memset(&tm, 0, sizeof(struct tm));
735 cal_util_update_tm_hour(&tm, 0);
739 r = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, &is_hour24);
744 else if(is_hour24 ==1 || is_hour24 == 2)
750 ERR("vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, &is_hour24) is failed");
755 for (i = 0; i < sizeof(time_block->tbs)/sizeof(time_block->tbs[0]); i++)
757 ly = cal_util_add_layout(time_block->parent, "main/day/tb/block");
761 cal_util_set_time_text(CAL_UTIL_GET_EDJ_DATA(ly), "text", NULL, CAL_UTIL_TIME_FORMAT_7, &tm);
764 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "AM", "AM");
765 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(ly), "show,AM", "prog");
766 } else if (i == 12) {
767 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "PM", "PM");
768 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(ly), "show,PM", "prog");
771 sprintf(tmp, "%02d", (i > 12 ? i - 12 : i));
772 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "text", tmp);
773 memset(tmp, 0x00, 8);
776 cal_util_update_tm_hour(&tm, 1);
778 evas_object_clip_set(ly, (Evas_Object*)time_block->clip);
779 evas_object_show(ly);
781 t = &time_block->tbs[i];
783 t->h = time_block->normal_height;
787 edje_object_signal_callback_add(CAL_UTIL_GET_EDJ_DATA(ly), "*", "edj", __cal_time_block_time_block_callback, t);
789 e = &time_block->ebs[i << 1];
791 e->base = edje_object_part_object_get(CAL_UTIL_GET_EDJ_DATA(ly), "evtbase/top");
795 e = &time_block->ebs[(i << 1) + 1];
797 e->base = edje_object_part_object_get(CAL_UTIL_GET_EDJ_DATA(ly), "evtbase/bottom");
807 static void __cal_time_resize_time_block(void *data, Evas *e, Evas_Object *obj, void *ei)
809 struct timeblock *time_block = data;
810 c_retm_if(!time_block || !time_block->ad, "input param is NULL");
815 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
817 if (!time_block->ad->is_landscape_mode) {
825 __cal_time_block_resize_time_block(time_block);
826 __cal_time_block_rearrange_time_block_after(time_block, 0);
827 __cal_time_block_move_event_block_slice(time_block);
830 struct timeblock* cal_time_block_create_time_block(Evas_Object *p, Evas_Object *clip, struct appdata *ad)
833 struct timeblock *time_block;
839 CAL_CALLOC(time_block, 1, struct timeblock);
841 double scale = elm_config_scale_get();
843 time_block->parent = p;
844 time_block->clip = clip;
845 time_block->normal_height = CAL_TIMEBLOCK_NORMAL_HEIGHT * scale;
846 time_block->expand_height = CAL_TIMEBLOCK_EXPAND_HEIGHT * scale;
849 __cal_time_block_add_time_block(time_block);
850 __cal_time_resize_time_block(time_block, NULL, p, NULL);
852 Evas_Object *ly = evas_object_data_get(p, "priv");
854 cal_day_update_expand(ly, 0);
858 static inline void __cal_time_block_clear_time_block(struct timeblock *time_block)
860 c_ret_if(!time_block);
862 struct timeblock_event *ev;
863 struct eventblock_slice *eb;
867 __cal_time_block_delete_event_block_slice_overlap(time_block);
869 for (i = 0; i < sizeof(time_block->ebs)/sizeof(time_block->ebs[0]); i++) {
870 eb = &time_block->ebs[i];
877 EINA_LIST_FOREACH(eb->list, l, ev) {
884 evas_object_del(ev->ly);
889 eb->list = eina_list_free(eb->list);
893 static void __cal_time_block_delete_time_block_slice(struct timeblock *time_block)
895 c_ret_if(!time_block);
897 struct timeblock_slice *tbs;
900 for (i = 0; i < sizeof(time_block->tbs)/sizeof(time_block->tbs[0]); i++) {
901 tbs = &time_block->tbs[i];
908 evas_object_clip_unset(tbs->ly);
910 edje_object_signal_callback_del(CAL_UTIL_GET_EDJ_DATA(tbs->ly), "*", "edj", __cal_time_block_time_block_callback);
912 evas_object_del(tbs->ly);
917 void cal_time_block_delete_time_block(struct timeblock **tb)
924 __cal_time_block_clear_time_block(*tb);
925 __cal_time_block_delete_time_block_slice(*tb);
927 if ((*tb)->long_press_timer)
928 ecore_timer_del((*tb)->long_press_timer);
934 Evas_Coord cal_time_block_get_min()
936 double scale = elm_config_scale_get();
937 return CAL_TIMEBLOCK_MIN_HEIGHT * scale;
940 Evas_Coord cal_time_block_get_max(struct timeblock *tb)
945 return tb->normal_height;
948 Evas_Coord cal_time_block_get_expand_max(struct timeblock *tb)
953 return tb->expand_height;
956 Evas_Coord cal_time_block_get_current(struct timeblock *tb)
961 return tb->ad->h_cur;
964 void cal_time_block_set_event_lock(struct timeblock *tb, Eina_Bool lock)
970 if (tb->lock && tb->dn) {
971 edje_object_signal_emit(tb->dn, "unselect", "prog");
976 void cal_time_block_unset_callback(struct timeblock *tb)
986 void cal_time_block_set_callback(struct timeblock *tb, void (*cb)(void *data,
987 struct timeblock *tb ,enum timeblock_event_type e, void *event_info),
997 void cal_time_block_clear_event(struct timeblock *time_block)
1001 c_retm_if(!time_block, "time_block is null");
1008 __cal_time_block_clear_time_block(time_block);
1010 for (i = 0; i < sizeof(time_block->tbs)/sizeof(time_block->tbs[0]); i++)
1011 time_block->tbs[i].cnt = 0;
1013 time_block->color = 0;
1016 Evas_Coord cal_time_block_get_first_event_y(struct timeblock *tb)
1026 for (i = 0; i < sizeof(tb->ebs)/sizeof(tb->ebs[0]); i++) {
1027 if (tb->ebs[i].real_sz> 0)
1029 h += ((tb->tbs[i/2].h)/2);
1034 int cal_time_block_get_default_current_height()
1036 double scale = elm_config_scale_get();
1037 return CAL_TIMEBLOCK_NORMAL_HEIGHT * scale;