[misc] Sycn with master branch.
[apps/core/preloaded/calendar.git] / src / base-time-block.c
1 /*
2   *
3   *  Copyright 2012  Samsung Electronics Co., Ltd
4   *
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
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 #include "base-time-block.h"
18 #include "day-time-block.h"
19
20 static void __cal_base_time_block_init(cal_base_time_block_h base_time_block);
21
22 cal_base_time_block_h cal_base_time_block_new(cal_base_type type, Evas_Object *parent, Evas_Object *clip, Evas_Object *clip_block, int current_hour, void *data)
23 {
24         cal_base_time_block_s *base_time_block = NULL;
25
26         switch (type) {
27                 case _CAL_BASE_TYPE_EVENT:
28                         base_time_block = (cal_base_time_block_s *)cal_day_time_block_create(data);
29                         break;
30                 default:
31                         return NULL;
32         }
33
34         double scale = elm_config_scale_get();
35         base_time_block->parent = parent;
36         base_time_block->clip = clip;
37         base_time_block->normal_height = TIME_BLOCK_NORMAL_HEIGHT * scale;
38         base_time_block->current_hour = current_hour;
39
40         __cal_base_time_block_init(base_time_block);
41
42         base_time_block->base_block = cal_base_block_new(type, parent, clip, data);
43
44         return base_time_block;
45 }
46
47 cal_base_time_block_h cal_base_time_block_create(cal_base_time_block_operations *base_operations, void *data)
48 {
49         c_retv_if(!base_operations, NULL);
50         c_retv_if(!base_operations->new_func_ptr, NULL);
51
52         cal_base_time_block_h base_time_block = base_operations->new_func_ptr(data);
53         c_retv_if(!base_time_block , NULL);
54
55         cal_base_time_block_s *p =  (cal_base_time_block_s *)base_time_block;
56
57         p->base_operations.new_func_ptr = base_operations->new_func_ptr;
58         p->base_operations.delete_func_ptr = base_operations->delete_func_ptr;
59         p->base_operations.update_func_ptr = base_operations->update_func_ptr;
60
61         return base_time_block;
62 }
63
64 static void __cal_base_time_block_delete(cal_base_time_block_h base_time_block)
65 {
66         c_ret_if(!base_time_block);
67
68         cal_base_time_block_s *p =  (cal_base_time_block_s *)base_time_block;
69
70         cal_base_time_block_slice *time_block_slice = NULL;
71
72         int i;
73
74         for (i = 0; i < TIME_BLOCK_SLICE_COUNT; i++) {
75                 time_block_slice = &p->time_block_slice_array[i];
76                 if (time_block_slice) {
77                         if (time_block_slice->ly) {
78                                 evas_object_clip_unset(time_block_slice->ly);
79                                 evas_object_del(time_block_slice->ly);
80                         }
81                 }
82         }
83
84         CAL_FREE(p);
85 }
86
87 static Eina_Bool __cal_base_time_block_foreach_figure_block_count_cb(cal_base_block_item_h block_item, int line_index, int height, void *user_data)
88 {
89         c_retv_if(!user_data, EINA_FALSE);
90         c_retv_if(!block_item, EINA_FALSE);
91
92         cal_base_time_block_s *p = user_data;
93         c_retv_if(!p->base_block, EINA_FALSE);
94
95         cal_base_time_block_slice *time_block_slice = NULL;
96         int index = 0;
97
98         for (index = line_index; index < line_index+height; index++) {
99                 if (0 == (line_index+2)%2) {
100                         time_block_slice = &p->time_block_slice_array[line_index >> 1];
101                         time_block_slice->slice_block_count++;
102                 } else {
103                         time_block_slice = &p->time_block_slice_array[(line_index-1) >> 1];
104                         time_block_slice->slice_block_count++;
105                 }
106         }
107
108         return EINA_TRUE;
109 }
110
111 void cal_base_time_block_figure_time_block_slice_block_count(cal_base_time_block_h base_time_block)
112 {
113         c_ret_if(!base_time_block);
114
115         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
116
117         cal_base_block_foreach_items(__cal_base_time_block_foreach_figure_block_count_cb, p->base_block, p);
118 }
119
120 void cal_base_time_block_clear_time_block_slice_block_count(cal_base_time_block_h base_time_block)
121 {
122         c_ret_if(!base_time_block);
123
124         int i;
125         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
126
127         for (i = 0; i < TIME_BLOCK_SLICE_COUNT; i++) {
128                 p->time_block_slice_array[i].slice_block_count= 0;
129         }
130 }
131
132 void cal_base_time_block_update(cal_base_time_block_h base_time_block)
133 {
134         c_ret_if(!base_time_block);
135
136         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
137         c_ret_if(!p->base_block);
138
139         if (p->base_operations.update_func_ptr) {
140                 p->base_operations.update_func_ptr(base_time_block);
141         } else {
142                 cal_base_time_block_clear_time_block_slice_block_count(base_time_block);
143
144                 cal_base_block_update(p->base_block);
145
146                 cal_base_time_block_figure_time_block_slice_block_count(base_time_block);
147         }
148 }
149
150 void cal_base_time_block_delete(cal_base_time_block_h base_time_block)
151 {
152         c_ret_if(!base_time_block);
153
154         cal_base_time_block_s *p =  (cal_base_time_block_s *)base_time_block;
155
156         if (p->base_operations.delete_func_ptr) {
157                 p->base_operations.delete_func_ptr(base_time_block);
158         }  else {
159                 cal_base_block_delete(p->base_block);
160                 __cal_base_time_block_delete(base_time_block);
161         }
162 }
163
164 static Evas_Object *__cal_base_time_block_add_time_block_slice_layout(cal_base_time_block_s *p, struct tm *hour_time, int hour_index)
165 {
166         c_retv_if(!p, NULL);
167         c_retv_if(!p->parent, NULL);
168         c_retv_if(!hour_time, NULL);
169
170         Evas_Object *ly = NULL;
171
172         ly = cal_util_add_layout(p->parent, p->name);
173         c_retv_if(!ly, NULL);
174
175         if(is_hour24) {
176                 cal_util_set_time_text(CAL_UTIL_GET_EDJ_DATA(ly), "text", NULL, CAL_UTIL_TIME_FORMAT_7, hour_time);
177         } else {
178                 if (0 == hour_index) {
179                         edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "AM", "AM");
180                         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(ly), "show,AM", "prog");
181                 }  else if (hour_index == TIME_BLOCK_DAY_HOURS) {
182                         edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "PM", "PM");
183                         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(ly), "show,PM", "prog");
184                 }
185
186                 char hour_text[8] = {0};
187                 sprintf(hour_text, "%02d", (hour_index > TIME_BLOCK_DAY_HOURS ? hour_index - TIME_BLOCK_DAY_HOURS : hour_index));
188                 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "text", hour_text);
189         }
190
191         if (TIME_BLOCK_DAY_HOURS <= hour_index) {
192                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(ly), "pm", "prog");
193         }
194
195         evas_object_clip_set(ly, (Evas_Object*)p->clip);
196         evas_object_show(ly);
197
198         return ly;
199 }
200
201 static void __cal_base_time_block_add_time_block_slices(cal_base_time_block_s *p)
202 {
203         c_ret_if(!p);
204         c_ret_if(!p->parent);
205
206         int i;
207         cal_base_time_block_slice *base_block_slice;
208
209         Evas_Object *ly;
210         struct tm tm;
211
212         memset(&tm, 0, sizeof(struct tm));
213         cal_util_update_tm_hour(&tm, 0);
214         tm.tm_hour = 0;
215         tm.tm_min = 0;
216
217         p->height = 0;
218
219         int event_slice_base_index = 0;
220         for (i = 0; i < TIME_BLOCK_SLICE_COUNT; i++) {
221                 ly = __cal_base_time_block_add_time_block_slice_layout(p, &tm, i);
222                 c_ret_if(!ly);
223
224                 cal_util_update_tm_hour(&tm, 1);
225
226                 base_block_slice = &p->time_block_slice_array[i];
227                 base_block_slice->ly = ly;
228                 base_block_slice->height = p->normal_height;
229                 base_block_slice->line_index = i;
230
231                 p->event_block_slice_object_array[event_slice_base_index++] = edje_object_part_object_get(CAL_UTIL_GET_EDJ_DATA(base_block_slice->ly), "evtbase/top");
232                 p->event_block_slice_object_array[event_slice_base_index++] = edje_object_part_object_get(CAL_UTIL_GET_EDJ_DATA(base_block_slice->ly), "evtbase/bottom");
233
234                 p->height += base_block_slice->height;
235         }
236 }
237
238 void cal_base_time_block_resize_time_block_slices(cal_base_time_block_h base_time_block)
239 {
240         c_ret_if(!base_time_block);
241
242         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
243
244         int i;
245         p->height = 0;
246
247         for (i = 0; i < TIME_BLOCK_SLICE_COUNT; i++) {
248                 cal_base_time_block_slice *time_block_slice = &p->time_block_slice_array[i];
249
250                 if (!time_block_slice->ly)
251                         continue;
252
253                 if ( TIME_BLOCK_TEXT_HEIGHT < time_block_slice->height) {
254                         if (time_block_slice->hide_text) {
255                                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(time_block_slice->ly), "show,text", "prog");
256                                 time_block_slice->hide_text = EINA_FALSE;
257                         }
258                 } else {
259                         if (!time_block_slice->hide_text) {
260                                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(time_block_slice->ly), "hide,text", "prog");
261                                 time_block_slice->hide_text = EINA_TRUE;
262                         }
263                 }
264
265                 evas_object_resize(time_block_slice->ly, p->width, time_block_slice->height);
266                 p->height += time_block_slice->height;
267         }
268 }
269
270 static void __cal_base_time_block_move_time_block_slices(cal_base_time_block_s *p)
271 {
272         int i;
273         cal_base_time_block_slice *time_block_slice_prev;
274         cal_base_time_block_slice *time_block_slice;
275
276         for (i = 1; i < TIME_BLOCK_SLICE_COUNT; i++) {
277                 time_block_slice = &p->time_block_slice_array[i];
278                 time_block_slice_prev = &p->time_block_slice_array[i - 1];
279
280                 time_block_slice->y = time_block_slice_prev->y + time_block_slice_prev->height;
281                 evas_object_move(time_block_slice->ly, time_block_slice->x, time_block_slice->y);
282         }
283 }
284
285 static void __cal_base_time_block_show_time_line(cal_base_time_block_s *p)
286 {
287         c_ret_if(!p);
288
289         int i;
290         cal_base_time_block_slice *time_block_slice;
291         int hour  = p->current_hour;
292
293         if(0 > hour || 23 < hour)
294                 return;
295
296         for(i = 0; i < TIME_BLOCK_SLICE_COUNT; i++) {
297                 time_block_slice = &p->time_block_slice_array[i];
298                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(time_block_slice->ly), "hide,line", "prog");
299                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(time_block_slice->ly), "hide,img", "prog");
300         }
301
302         if(NULL != p->time_block_slice_array[hour].ly) {
303                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->time_block_slice_array[hour].ly), "show,line", "prog");
304                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->time_block_slice_array[hour].ly), "show,img", "prog");
305         }
306 }
307
308 static void __cal_base_time_block_init(cal_base_time_block_h base_time_block)
309 {
310         c_ret_if(!base_time_block);
311
312         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
313
314         __cal_base_time_block_add_time_block_slices(p);
315
316         cal_base_time_block_resize_time_block_slices(base_time_block);
317         __cal_base_time_block_move_time_block_slices(p);
318         __cal_base_time_block_show_time_line(p);
319 }
320
321 static Eina_Bool __cal_base_time_block_foreach_move_event_block_cb(cal_base_block_item_h block_item, int line_index, int height, void *user_data)
322 {
323         c_retv_if(!user_data, EINA_FALSE);
324         c_retv_if(!block_item, EINA_FALSE);
325
326         cal_base_time_block_s *p = user_data;
327         c_retv_if(!p->base_block, EINA_FALSE);
328
329         Evas_Object *obj_base = NULL;
330
331         obj_base = p->event_block_slice_object_array[line_index];
332         c_retv_if(!obj_base, EINA_FALSE);
333
334         Evas_Coord_Rectangle base = {0};
335         cal_util_get_geometry(&base, obj_base);
336
337         cal_base_block_move_item(p->base_block, block_item, &base);
338
339         return EINA_TRUE;
340 }
341
342 void cal_base_time_block_move_event_blocks(cal_base_time_block_h base_time_block)
343 {
344         c_ret_if(!base_time_block);
345         cal_base_time_block_s *p = base_time_block;
346
347         cal_base_block_foreach_items(__cal_base_time_block_foreach_move_event_block_cb, p->base_block, p);
348 }
349
350 void cal_base_time_block_move(cal_base_time_block_h base_time_block, Evas_Coord x, Evas_Coord y)
351 {
352         c_ret_if(!base_time_block);
353
354         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
355
356         int i;
357         cal_base_time_block_slice *time_block_slice = NULL;
358
359         p->x = x;
360         p->y = y;
361
362         for (i = 0; i < TIME_BLOCK_SLICE_COUNT; i++) {
363                 time_block_slice = &p->time_block_slice_array[i];
364                 if (!time_block_slice->ly)
365                         continue;
366
367                 evas_object_move(time_block_slice->ly, x, y);
368                 time_block_slice->x = x;
369                 time_block_slice->y = y;
370
371                 y += time_block_slice->height;
372         }
373
374         cal_base_time_block_move_event_blocks(p);
375
376 }
377
378 void cal_base_time_block_get_geometry(cal_base_time_block_h base_time_block, Evas_Coord_Rectangle *r)
379 {
380         c_ret_if(!base_time_block);
381         c_ret_if(!r);
382
383         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
384
385         r->x = p->x;
386         r->y = p->y;
387         r->w = p->width;
388         r->h = p->height;
389 }
390
391 void cal_base_time_block_move_to_time_line(cal_base_time_block_h base_time_block)
392 {
393         c_ret_if(!base_time_block);
394
395         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
396
397         cal_base_time_block_slice *time_block_slice;
398         int hour  = p->current_hour;
399
400         Evas_Coord_Rectangle time_block_r, scroller_r;
401         cal_base_time_block_get_geometry(base_time_block, &time_block_r);
402
403         cal_util_get_geometry(&scroller_r, p->parent);
404
405         if (time_block_r.h <=  scroller_r.h) {
406                 return;
407         }
408
409         if (0 < hour && hour < TIME_BLOCK_SLICE_COUNT) {
410                 time_block_slice = &p->time_block_slice_array[hour];
411                 int dis_offset = time_block_slice->y - (scroller_r.y + scroller_r.h/2);
412
413                 if (dis_offset < 0) {
414                         if (scroller_r.y < time_block_r.y + abs(dis_offset)) {
415                                 elm_scroller_region_show(p->parent, 0, 0, 0, scroller_r.h);
416                         } else {
417                                 elm_scroller_region_show(p->parent, 0, scroller_r.y - time_block_r.y - abs(dis_offset), 0, scroller_r.h);
418                         }
419                 } else if (0 < dis_offset) {
420                         if (time_block_r.y - dis_offset + time_block_r.h < scroller_r.y + scroller_r.h) {
421                                 elm_scroller_region_show(p->parent, 0,  time_block_r.h - scroller_r.h, 0, scroller_r.h);
422                         } else {
423                                 elm_scroller_region_show(p->parent, 0, scroller_r.y - time_block_r.y + dis_offset, 0, scroller_r.h);
424                         }
425                 }
426         }
427 }
428
429 int cal_base_time_block_get_time_block_slice_index_by_coord_point(cal_base_time_block_h base_time_block, Evas_Coord_Point *mouse_down_coord)
430 {
431         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
432         c_retv_if(!p, -1);
433
434         int i;
435         cal_base_time_block_slice *time_block_slice  = NULL;
436
437         for (i = 1; i < TIME_BLOCK_SLICE_COUNT; i++) {
438                 time_block_slice = &p->time_block_slice_array[i];
439
440                 if (mouse_down_coord->y < time_block_slice->y) {
441                         return i-1;
442                 }
443         }
444
445         return -1;
446 }
447
448 void    cal_base_time_block_show(cal_base_time_block_h base_time_block)
449 {
450         c_ret_if(!base_time_block);
451
452         int i = 0;
453         cal_base_time_block_slice *time_block_slice = NULL;
454         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
455
456         for (i = 0; i < TIME_BLOCK_SLICE_COUNT; i++) {
457                 time_block_slice = &p->time_block_slice_array[i];
458                 c_ret_if(!time_block_slice);
459                 c_ret_if(!time_block_slice->ly);
460
461                 evas_object_show(time_block_slice->ly);
462         }
463
464         cal_base_block_show(p->base_block);
465 }
466
467 void    cal_base_time_block_hide(cal_base_time_block_h base_time_block)
468 {
469         c_ret_if(!base_time_block);
470
471         int i = 0;
472         cal_base_time_block_slice *time_block_slice = NULL;
473         cal_base_time_block_s *p = (cal_base_time_block_s *)base_time_block;
474
475         for (i = 0; i < TIME_BLOCK_SLICE_COUNT; i++) {
476                 time_block_slice = &p->time_block_slice_array[i];
477                 c_ret_if(!time_block_slice);
478                 c_ret_if(!time_block_slice->ly);
479
480                 evas_object_hide(time_block_slice->ly);
481         }
482
483         cal_base_block_hide(p->base_block);
484 }
485