731e7b105b0e0ba8968b08ac73f6059b3f267daf
[apps/core/preloaded/calendar.git] / src / day-time-block.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 #include "day-time-block.h"
18
19 static const char *_name = "main/day/time/timeblock";
20
21 typedef struct cal_day_time_block{
22         cal_base_time_block_s base_time_block;
23
24         struct appdata *ad;
25
26         Evas_Coord contract_height;
27         Evas_Coord expand_height;
28         Evas_Coord h_contract;
29
30         void (*event_cb)(void *data, int event_type, void *event_info);
31         void *event_cb_data;
32
33         int current_hour;
34 } cal_day_time_block_s;
35
36 static cal_base_time_block_h __cal_day_time_block_new(void *data);
37
38 cal_base_time_block_operations day_time_block_operations = {
39         __cal_day_time_block_new,
40         NULL,
41         NULL,
42 };
43
44 static cal_base_time_block_h __cal_day_time_block_new(void *data)
45 {
46         c_retv_if(!data, NULL);
47
48         cal_day_time_block_s *p;
49
50         CAL_CALLOC(p, 1, cal_day_time_block_s);
51
52         double scale = elm_config_scale_get();
53         Evas_Coord width;
54         Evas_Coord height;
55
56         p->ad = (struct appdata *)data;
57         ((cal_base_time_block_s *)p)->name = _name;
58         p->expand_height = TIME_BLOCK_EXPAND_HEIGHT * scale;
59         p->contract_height = TIME_BLOCK_CONTENT_HEIGHT * scale;
60         p->h_contract = TIME_BLOCK_CONTRACT_HEIGHT * scale;
61
62         ecore_x_window_size_get(ecore_x_window_root_first_get(), &width, &height);
63
64         if (!p->ad->is_landscape_mode) {
65                 ((cal_base_time_block_s *)p)->width = width;
66                 ((cal_base_time_block_s *)p)->height = height;
67         } else {
68                 ((cal_base_time_block_s *)p)->width = height;
69                 ((cal_base_time_block_s *)p)->height = width;
70         }
71
72         return p;
73 }
74
75 cal_base_time_block_h cal_day_time_block_create(void *data)
76 {
77         return cal_base_time_block_create(&day_time_block_operations, data);
78 }
79
80 Eina_Bool cal_day_time_block_hint_clicked(cal_day_time_block_h day_time_block, Evas_Coord_Point *mouse_down_coord)
81 {
82         c_retv_if(!day_time_block, EINA_FALSE);
83         c_retv_if(!mouse_down_coord, EINA_FALSE);
84
85         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
86
87         Eina_Bool is_event_clicked = EINA_FALSE;
88         calendar_record_h record = NULL;
89         is_event_clicked = cal_day_event_block_hint_clicked(((cal_base_time_block_s *)p)->base_block, mouse_down_coord, &record);
90
91         if (!is_event_clicked) {
92                 c_retv_if(p->ad->is_contracted, EINA_FALSE);
93
94                 int time_slice_index = cal_base_time_block_get_time_block_slice_index_by_coord_point(p, mouse_down_coord);
95                 c_retv_if(-1 == time_slice_index, EINA_FALSE);
96
97                 if (p->event_cb) {
98                         p->event_cb(p->event_cb_data, TIME_BLOCK_SLICE_CLICEKD, (void *)time_slice_index);
99                 }
100         } else {
101                 if (!record) {
102                         p->event_cb(p->event_cb_data, EVEN_BLOCK_MORE_EVENT_CLICEKD, (void *)record);
103                 } else {
104                         p->event_cb(p->event_cb_data, EVEN_BLOCK_EVENT_CLICEKD, (void *)record);
105                 }
106
107         }
108
109         return is_event_clicked;
110 }
111
112 void cal_day_time_block_set_callback(cal_day_time_block_h day_time_block,
113                 void (*event_cb)(void *data, int event_type, void *event_info),
114                 void *data)
115 {
116         c_ret_if(!day_time_block);
117
118         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
119
120         p->event_cb = event_cb;
121         p->event_cb_data = data;
122 }
123
124 void cal_day_time_block_unset_callback(cal_day_time_block_h day_time_block)
125 {
126         c_ret_if(!day_time_block);
127
128
129         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
130         p->event_cb = NULL;
131         p->event_cb_data = NULL;
132 }
133
134 Eina_Bool cal_day_time_block_hint_longpress(cal_day_time_block_h day_time_block, Evas_Coord_Point *mouse_down_coord)
135 {
136         c_retv_if(!day_time_block, EINA_FALSE);
137         c_retv_if(!mouse_down_coord, EINA_FALSE);
138
139         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
140         c_retv_if(!p->ad, EINA_FALSE);
141         c_retv_if(p->ad->is_contracted, EINA_FALSE);
142
143         Eina_Bool is_event_longpressed = EINA_FALSE;
144         is_event_longpressed = cal_day_event_block_hint_longpress(((cal_base_time_block_s *)p)->base_block, mouse_down_coord);
145         if (!is_event_longpressed) {
146                 int time_slice_index = cal_base_time_block_get_time_block_slice_index_by_coord_point(p, mouse_down_coord);
147                 c_retv_if(-1 == time_slice_index, EINA_FALSE);
148
149                 if (p->event_cb) {
150                         p->event_cb(p->event_cb_data, TIME_BLOCK_SLICE_LONGPRESS, (void *)time_slice_index);
151                 }
152         } else {
153                         cal_day_event_block_longpress_callback(((cal_base_time_block_s *)p)->base_block);
154                         p->event_cb(p->event_cb_data, EVEN_BLOCK_EVENT_LONGPRESS, NULL);
155
156         }
157
158         return is_event_longpressed;
159 }
160
161 Eina_Bool cal_day_time_block_hint_quit_event_moveable_state(cal_day_time_block_h day_time_block, Evas_Coord_Point *mouse_down_coord)
162 {
163         c_retv_if(!day_time_block, EINA_FALSE);
164         c_retv_if(!mouse_down_coord, EINA_FALSE);
165
166         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
167
168         return cal_day_event_block_hint_quit_event_moveable_state(((cal_base_time_block_s *)p)->base_block, mouse_down_coord);
169 }
170
171 static void __cal_day_time_block_moving_time_block_callback(void *user_data, Evas_Coord time_block_y)
172 {
173         c_ret_if(!user_data);
174
175         cal_day_time_block_h day_time_block = user_data;
176
177         Evas_Coord_Rectangle  timeblock_r;
178
179         cal_base_time_block_get_geometry(day_time_block, &timeblock_r);
180
181         cal_base_time_block_move(day_time_block, timeblock_r.x, time_block_y);
182 }
183
184 void cal_day_time_block_moving_moveable_event(cal_day_time_block_h day_time_block, Evas_Coord_Point *mouse_move_coord, Evas_Coord_Point *mouse_down_coord)
185 {
186         c_ret_if(!day_time_block);
187         c_ret_if(!mouse_move_coord);
188         c_ret_if(!mouse_down_coord);
189
190         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
191
192         Evas_Coord_Rectangle timeblock_r;
193
194         cal_base_time_block_get_geometry(day_time_block, &timeblock_r);
195
196         cal_day_event_block_moving_moveable_event(((cal_base_time_block_s *)p)->base_block, mouse_move_coord, mouse_down_coord, __cal_day_time_block_moving_time_block_callback, day_time_block, timeblock_r.y, timeblock_r.h);
197 }
198
199 static int __cal_day_time_block_figure_event_block_border_line_index(cal_day_time_block_s *p, Evas_Object *event_obj, Eina_Bool is_bottom_border)
200 {
201         c_retv_if(!event_obj, -1);
202         c_retv_if(!p, -1);
203
204         Evas_Object *obj_base = NULL;
205         int line_index = 0;
206         Evas_Coord_Rectangle r;
207         Evas_Coord event_y, event_block_slice_y;
208
209         cal_util_get_geometry(&r, event_obj);
210         if (!is_bottom_border) {
211                 event_y = r.y;
212         } else {
213                 event_y = r.y + r.h;
214         }
215
216         for (line_index = 0; line_index < EVENT_SLICE_COUNT; line_index++) {
217
218                 obj_base = ((cal_base_time_block_s *)p)->event_block_slice_object_array[line_index];
219                 c_retv_if(!obj_base, -1);
220
221                 cal_util_get_geometry(&r, obj_base);
222
223                 if (event_y <= r.y) {
224
225                         event_block_slice_y = r.y;
226                         if (line_index != 0) {
227                                 obj_base = ((cal_base_time_block_s *)p)->event_block_slice_object_array[line_index-1];
228                                 c_retv_if(!obj_base, -1);
229
230                                 cal_util_get_geometry(&r, obj_base);
231
232                                 if (event_y - r.y < event_block_slice_y - event_y)
233                                         return line_index-1;
234                         }
235
236                         return line_index;
237                 }
238         }
239
240         return line_index;
241 }
242
243 void cal_day_time_block_disable_moving_moveable_event(cal_day_time_block_h day_time_block, Evas_Coord_Point *mouse_move_coord, Evas_Coord_Point *mouse_down_coord)
244 {
245         c_ret_if(!day_time_block);
246         c_ret_if(!mouse_move_coord);
247         c_ret_if(!mouse_down_coord);
248
249         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
250         Evas_Coord_Rectangle scroller_r, timeblock_r;
251
252         Evas_Object *moveable_event = NULL;
253         Evas_Object *moveable_event_border = NULL;
254
255
256         cal_day_event_block_get_moveable_event_objects(((cal_base_time_block_s *)p)->base_block, &moveable_event, &moveable_event_border);
257         c_ret_if(!moveable_event);
258         c_ret_if(!moveable_event_border);
259
260         int new_ebs_idx = __cal_day_time_block_figure_event_block_border_line_index(p, moveable_event, EINA_FALSE);
261         int end_ebs_idx = __cal_day_time_block_figure_event_block_border_line_index(p, moveable_event, EINA_TRUE);
262         c_ret_if(new_ebs_idx < 0);
263
264         int ev_sz = (0 == end_ebs_idx - new_ebs_idx) ? 1: (end_ebs_idx - new_ebs_idx);
265
266         cal_day_event_block_update_moveable_event(((cal_base_time_block_s *)p)->base_block, new_ebs_idx, ev_sz);
267
268         cal_base_time_block_move_event_blocks(p);
269
270         cal_util_get_geometry(&scroller_r, ((cal_base_time_block_s *)p)->parent);
271         cal_base_time_block_get_geometry(day_time_block, &timeblock_r);
272         elm_scroller_region_show(((cal_base_time_block_s *)p)->parent, 0, scroller_r.y - timeblock_r.y, 0, scroller_r.h);
273
274         cal_base_time_block_figure_time_block_slice_block_count(p);
275 }
276
277 static int __cal_day_time_block_find_time_block_slice_index(cal_day_time_block_s *p, Evas_Coord y)
278 {
279         c_retv_if(!p, -1);
280
281         int i;
282         cal_base_time_block_slice *time_block_slice = NULL;
283
284         for (i = 1; i < TIME_BLOCK_SLICE_COUNT; i++) {
285                 time_block_slice = &((cal_base_time_block_s *)p)->time_block_slice_array[i];
286
287                 if (y < time_block_slice->y)
288                         return i - 1;
289         }
290
291         return i - 1;
292 }
293
294 static inline void __cal_day_time_block_set_contract_size(cal_day_time_block_s *p, Evas_Coord h)
295 {
296         c_ret_if(!p);
297         c_ret_if(!p->ad);
298
299         cal_base_time_block_slice *time_block_slice = NULL;
300
301         int i = 0;
302         int j = 0;
303         int k = 0;
304
305         int hour  = p->current_hour;
306
307         for(k = 0; k < TIME_BLOCK_SLICE_COUNT; k++) {
308                 time_block_slice = &((cal_base_time_block_s *)p)->time_block_slice_array[k];
309                 time_block_slice->is_contracted = EINA_FALSE;
310         }
311
312         while(i < TIME_BLOCK_SLICE_COUNT) {
313                 time_block_slice = &((cal_base_time_block_s *)p)->time_block_slice_array[i];
314                 if (time_block_slice->slice_block_count== 0) {
315                         if(hour == i) {
316                                 i += 1;
317                                 time_block_slice->height = ((cal_base_time_block_s *)p)->normal_height;
318                                 continue;
319                         } else {
320                                 time_block_slice->is_contracted = EINA_TRUE;
321                                 time_block_slice->height = p->h_contract;
322                         }
323
324                         for(j = i+1; j < TIME_BLOCK_SLICE_COUNT; j++) {
325                                 time_block_slice = &((cal_base_time_block_s *)p)->time_block_slice_array[j];
326                                 if (time_block_slice->slice_block_count == 0) {
327                                         if(hour == j) {
328                                                 i = j;
329                                                 break;
330                                         } else {
331                                                 time_block_slice->height = h;
332                                         }
333                                 } else {
334                                         i = j;
335                                         break;
336                                 }
337                         }
338
339                         i = j;
340
341                 } else {
342                         i++;
343                 }
344         }
345
346         p->ad->h_cur = p->h_contract;
347
348         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(((cal_base_time_block_s *)p)->time_block_slice_array[0].ly), "hide,AM", "prog");
349         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(((cal_base_time_block_s *)p)->time_block_slice_array[12].ly), "hide,PM", "prog");
350 }
351
352 static inline void __cal_day_time_block_set_normal_size(cal_day_time_block_s *p, Evas_Coord h)
353 {
354         c_ret_if(!p);
355         c_ret_if(!p->ad);
356
357         int i;
358         struct appdata *ad = p->ad;
359
360         cal_base_time_block_slice *time_block_slice = NULL;
361
362         if (ad->is_magnifying) {
363                 if (p->expand_height < h)
364                         h = p->expand_height;
365
366                 if (h < ((cal_base_time_block_s *)p)->normal_height)
367                         h = ((cal_base_time_block_s *)p)->normal_height;
368         } else {
369
370                 if (!ad->is_contracted) {
371                         if (p->expand_height <= h)
372                                 h = p->expand_height;
373
374                         if (h < p->contract_height)
375                                 h = p->contract_height;
376                 } else {
377                         if (((cal_base_time_block_s *)p)->normal_height <= h)
378                                 h = ((cal_base_time_block_s *)p)->normal_height;
379
380                         if (h < p->contract_height)
381                                 h = p->contract_height;
382                 }
383         }
384
385         for (i = 0; i < TIME_BLOCK_SLICE_COUNT; i++) {
386                 time_block_slice = &((cal_base_time_block_s *)p)->time_block_slice_array[i];
387                 time_block_slice->is_contracted = EINA_FALSE;
388
389                 if (time_block_slice->slice_block_count == 0)
390                         time_block_slice->height = h;
391                 else {
392                         if (((cal_base_time_block_s *)p)->normal_height < h) {
393                                 time_block_slice->height = h;
394                         } else {
395                                 time_block_slice->height = ((cal_base_time_block_s *)p)->normal_height;
396                         }
397                 }
398         }
399
400         p->ad->h_cur = h;
401
402         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(((cal_base_time_block_s *)p)->time_block_slice_array[0].ly), "show,AM", "prog");
403         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(((cal_base_time_block_s *)p)->time_block_slice_array[12].ly), "show,PM", "prog");
404 }
405
406 static inline void __cal_day_time_block_set_time_block_slice_height(cal_day_time_block_s *p, Evas_Coord h, Eina_Bool is_set_contract)
407 {
408         c_ret_if(!p);
409
410         if (is_set_contract) {
411                 __cal_day_time_block_set_contract_size(p, h);
412         } else {
413                 __cal_day_time_block_set_normal_size(p, h);;
414         }
415 }
416
417 static void __cal_day_time_block_rearrange_time_block_after(cal_day_time_block_s *p, int idx)
418 {
419         c_ret_if(!p);
420
421         int i;
422         cal_base_time_block_slice *time_block_slice_prev;
423         cal_base_time_block_slice *time_block_slice;
424
425         for (i = idx + 1; i < TIME_BLOCK_SLICE_COUNT; i++) {
426                 time_block_slice = &((cal_base_time_block_s *)p)->time_block_slice_array[i];
427                 time_block_slice_prev = &((cal_base_time_block_s *)p)->time_block_slice_array[i - 1];
428
429                 time_block_slice->y = time_block_slice_prev->y + time_block_slice_prev->height;
430                 evas_object_move(time_block_slice->ly, time_block_slice->x, time_block_slice->y);
431         }
432 }
433
434 static inline void __cal_day_time_block_rearrange_time_block_slice(cal_day_time_block_s *p, int idx)
435 {
436         c_ret_if(!p);
437
438         cal_base_time_block_slice *time_block_slice;
439         cal_base_time_block_slice *time_block_slice_next;
440         int i;
441
442         __cal_day_time_block_rearrange_time_block_after(p, idx);
443
444         for (i = idx - 1; i >= 0; i--) {
445                 time_block_slice = &((cal_base_time_block_s *)p)->time_block_slice_array[i];
446                 time_block_slice_next = &((cal_base_time_block_s *)p)->time_block_slice_array[i + 1];
447
448                 time_block_slice->y = time_block_slice_next->y - time_block_slice->height;
449                 evas_object_move(time_block_slice->ly, time_block_slice->x, time_block_slice->y);
450         }
451
452         ((cal_base_time_block_s *)p)->y = ((cal_base_time_block_s *)p)->time_block_slice_array[0].y;
453 }
454
455 void cal_day_time_block_resize(cal_day_time_block_h day_time_block, Evas_Coord y, Evas_Coord h, Eina_Bool is_set_contract)
456 {
457         c_ret_if(!day_time_block);
458
459         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
460
461         int time_block_slice_index;
462
463         time_block_slice_index = __cal_day_time_block_find_time_block_slice_index(p, y);
464
465         __cal_day_time_block_set_time_block_slice_height(p, h, is_set_contract);
466
467         cal_base_time_block_resize_time_block_slices(p);
468
469         __cal_day_time_block_rearrange_time_block_slice(p, time_block_slice_index);
470
471         cal_base_time_block_move_event_blocks(p);
472 }
473
474 Evas_Coord cal_day_time_block_get_max(cal_day_time_block_h day_time_block)
475 {
476         c_retv_if(!day_time_block, 0);
477
478         cal_base_time_block_s *p = (cal_base_time_block_s *)day_time_block;
479
480         return p->normal_height;
481 }
482
483 Evas_Coord cal_day_time_block_get_min()
484 {
485         double scale = elm_config_scale_get();
486         return TIME_BLOCK_MIN_HEIGHT * scale;
487 }
488
489
490 Evas_Coord cal_day_time_block_get_expand_max(cal_day_time_block_h day_time_block)
491 {
492         c_retv_if(!day_time_block, 0);
493
494         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
495
496         return p->expand_height;
497 }
498
499 Evas_Coord cal_day_time_block_get_current(cal_day_time_block_h day_time_block)
500 {
501         c_retv_if(!day_time_block, 0);
502
503         cal_day_time_block_s *p = (cal_day_time_block_s *)day_time_block;
504
505
506         return p->ad->h_cur;
507 }
508