Version : 150811
[apps/native/sample/adventure.git] / src / item.c
1 #include <Elementary.h>
2 #include <system_settings.h>
3 #include <time.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <app.h>
7
8 #include "log.h"
9 #include "conf.h"
10 #include "util.h"
11 #include "city.h"
12 #include "item.h"
13 #include "main_view.h"
14 #include "scroller.h"
15 #include "popup.h"
16 #include "map.h"
17
18 #define _EDJ(o) elm_layout_edje_get(o)
19 #define MAX_CITY 5
20
21 const char *const DATA_KEY_CITY = "city";
22 const char *const DATA_KEY_MAIN_VIEW_INFO = "mvi";
23
24 const char *const ITEM_EDJE = "item.edj";
25 static int color_index[MAX_CITY] = { 0, 0, 0, 0, 0 };
26
27 void _text_set_here_time(Evas_Object *item, const char *part)
28 {
29         char *timezone_str = NULL;
30         struct tm *local_time = NULL;
31
32         int ret = SYSTEM_SETTINGS_ERROR_NONE;
33         time_t t = 0;
34         char time_result[PATH_LEN] = {0, };
35
36         ret_if(!item);
37         ret_if(!part);
38
39         local_time = localtime(&t);
40         ret_if(!local_time);
41
42         ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_TIMEZONE, &timezone_str);
43         if (ret != SYSTEM_SETTINGS_ERROR_NONE)
44                 _E("cannot get the timezone string");
45
46         /* Timezone
47            Asia/Seoul
48          */
49         if (local_time->tm_gmtoff >= 0)
50                 snprintf(time_result, sizeof(time_result), "%s, +%ld", timezone_str, local_time->tm_gmtoff / 3600);
51         else
52                 snprintf(time_result, sizeof(time_result), "%s, %ld", timezone_str, local_time->tm_gmtoff / 3600);
53
54         free(timezone_str);
55
56         elm_object_part_text_set(item, part, timezone_str);
57 }
58
59 static void _item_typing_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
60 {
61         item_destroy_typing(obj);
62 }
63
64 static void _item_typing_down_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
65 {
66         _D("An item is down");
67 }
68
69 static void _item_typing_up_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
70 {
71         Evas_Object *item = obj;
72         Evas_Object *selecting_item = NULL;
73         main_view_s *main_view_info = data;
74         int city = 0;
75         int count = 0;
76
77         ret_if(!item);
78         ret_if(!main_view_info);
79         ret_if(!main_view_info->city_list);
80
81         _D("An item is selected");
82
83         if (scroller_is_scrolling(main_view_info->searchlist))
84                 return;
85
86         count = scroller_count_item(main_view_info->city_list);
87         if (count + 1 > MAXIMUM_SELECTED_CITY) {
88                 Evas_Object *popup = NULL;
89                 _D("Cities selected are limited.");
90                 popup = popup_create_text(main_view_info->main_view, "Maximum number of cities reached");
91                 ret_if(!popup);
92                 return;
93         }
94
95         city = (int) evas_object_data_get(item, DATA_KEY_CITY);
96         selecting_item = item_create_selecting(main_view_info->city_list, city, 0, main_view_info);
97         ret_if(!selecting_item);
98         scroller_append_item(main_view_info->city_list, selecting_item);
99         count++;
100
101         if (count > 1) {
102                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,hide", "");
103                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,next_btn,show", "");
104         } else {
105                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,show", "");
106                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,next_btn,hide", "");
107         }
108 }
109
110 Evas_Object *item_create_typing(Evas_Object *parent, int city, main_view_s *main_view_info)
111 {
112         Evas_Object *item = NULL;
113         city_s *city_info = NULL;
114
115         char *path = NULL;
116         char full_path[PATH_LEN] = {0, };
117         char city_str[PATH_LEN] = {0, };
118
119         retv_if(!parent, NULL);
120
121         path = app_get_resource_path();
122         retv_if(!path, NULL);
123
124         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
125         free(path);
126
127         item = elm_layout_add(parent);
128         retv_if(!item, NULL);
129
130         elm_layout_file_set(item, full_path, "item_typing");
131
132         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
133         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
134         evas_object_data_set(item, DATA_KEY_CITY, (void *) city);
135         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_typing_del_cb, NULL);
136         elm_object_signal_callback_add(item, "down", "item", _item_typing_down_cb, NULL);
137         elm_object_signal_callback_add(item, "up", "item", _item_typing_up_cb, main_view_info);
138
139         evas_object_show(item);
140
141         if (city < 0) {
142                 elm_object_part_text_set(item, "city", "No results");
143                 elm_object_signal_emit(item, "disable", "item");
144                 return item;
145         }
146
147         city_info = city_get();
148         if (!city_info) {
149                 _E("Critical, no city information");
150                 evas_object_del(item);
151                 return NULL;
152         }
153
154         snprintf(city_str, sizeof(city_str), "%s, %s", city_info[city].name, city_info[city].nation);
155         elm_object_part_text_set(item, "city", city_str);
156
157         return item;
158 }
159
160 void item_destroy_typing(Evas_Object *item)
161 {
162         ret_if(!item);
163
164         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_typing_del_cb);
165         elm_object_signal_callback_del(item, "down", "item", _item_typing_down_cb);
166         elm_object_signal_callback_del(item, "up", "item", _item_typing_up_cb);
167
168         evas_object_data_del(item, DATA_KEY_CITY);
169         evas_object_del(item);
170 }
171
172 static void _item_selecting_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
173 {
174         item_destroy_selecting(obj);
175 }
176
177 static void _delete_selecting_item_cb(void *data, Evas_Object *obj, void *event_info)
178 {
179         main_view_s *main_view_info = NULL;
180         Evas_Object *item = data;
181         int count = 0;
182         int ci = 0;
183
184         _D("clicked, delete the selected item");
185
186         ret_if(!item);
187
188         main_view_info = evas_object_data_get(item, DATA_KEY_MAIN_VIEW_INFO);
189         ret_if(!main_view_info);
190
191         ci = (int) evas_object_data_get(item, "color_index");
192
193         if (EINA_FALSE == remove_city_from_map(ci))
194                 _E("cannot remove the city");
195
196         color_index[ci] = 0;
197         item_destroy_selecting(item);
198
199         count = scroller_count_item(main_view_info->city_list);
200         if (count > 1) {
201                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,hide", "");
202                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,next_btn,show", "");
203         } else {
204                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,add_description,show", "");
205                 elm_object_signal_emit(main_view_info->main_view, "momentic,state,next_btn,hide", "");
206         }
207 }
208
209 Evas_Object *item_create_selecting(Evas_Object *parent, int city, int color, main_view_s *main_view_info)
210 {
211         Evas_Object *item = NULL;
212         Evas_Object *btn = NULL;
213         city_s *city_info = NULL;
214         selecting_info_s *selecting_info = NULL;
215
216         char *path = NULL;
217         char full_path[PATH_LEN] = {0, };
218         char city_str[PATH_LEN] = {0, };
219         char gmt_str[PATH_LEN] = {0, };
220         char color_str[16] = {0, };
221
222         retv_if(!parent, NULL);
223
224         city_info = city_get();
225         goto_if(!city_info, error);
226
227         int i = 0;
228         for (i = 0; i < MAX_CITY; i++) {
229                 if (color_index[i]) continue;
230
231                 if (EINA_FALSE == add_city_to_map(i, &city_info[city])) {
232                         _E("cannot add a city to the map");
233                         return NULL;
234                 }
235                 break;
236         }
237
238         path = app_get_resource_path();
239         retv_if(!path, NULL);
240
241         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
242         free(path);
243
244         selecting_info = calloc(1, sizeof(selecting_info_s));
245         retv_if(!selecting_info, NULL);
246         selecting_info->city = city;
247         selecting_info->color = color;
248
249         item = elm_layout_add(parent);
250         retv_if(!item, NULL);
251
252         elm_layout_file_set(item, full_path, "item_selecting");
253
254         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
255         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
256         evas_object_data_set(item, DATA_KEY_MAIN_VIEW_INFO, main_view_info);
257         evas_object_data_set(item, DATA_KEY_SELECTING, selecting_info);
258         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_selecting_del_cb, NULL);
259         evas_object_show(item);
260
261         evas_object_data_set(item, "color_index", (void *) i);
262         color_index[i] = 1;
263
264         btn = elm_button_add(item);
265         if (btn) {
266                 elm_object_style_set(btn, "transparent");
267                 elm_object_part_content_set(item, "delete_event", btn);
268                 evas_object_smart_callback_add(btn, "clicked", _delete_selecting_item_cb, item);
269                 evas_object_show(btn);
270         }
271
272         snprintf(city_str, sizeof(city_str), "%s, %s", city_info[city].name, city_info[city].nation);
273         elm_object_part_text_set(item, "city", city_str);
274
275         if (city_info[city].timezone > 0)
276                 snprintf(gmt_str, sizeof(gmt_str), "GMT +%.1f", city_info[city].timezone);
277         else 
278                 snprintf(gmt_str, sizeof(gmt_str), "GMT %.1f", city_info[city].timezone);
279
280         elm_object_part_text_set(item, "gmt", gmt_str);
281
282         if (color) {
283                 snprintf(color_str, sizeof(color_str), "%d", color);
284                 elm_object_signal_emit(item, color_str, "mark");
285         }
286
287         return item;
288
289 error:
290         if (item)
291                 evas_object_del(item);
292
293         if (selecting_info)
294                 free(selecting_info);
295
296         return NULL;
297 }
298
299 void item_destroy_selecting(Evas_Object *item)
300 {
301         selecting_info_s *selecting_info = NULL;
302
303         ret_if(!item);
304
305         evas_object_data_del(item, DATA_KEY_MAIN_VIEW_INFO);
306         selecting_info = evas_object_data_del(item, DATA_KEY_SELECTING);
307         evas_object_data_del(item, "color_index");
308         free(selecting_info);
309
310         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_selecting_del_cb);
311
312         evas_object_del(item);
313 }
314
315 void _text_set_local_time(Evas_Object *item, const char *part, int city, struct tm *global_time)
316 {
317         city_s *city_info = NULL;
318         int hour = global_time->tm_hour;
319         int minute = global_time->tm_min;
320
321         char time_result[PATH_LEN] = {0, };
322
323         ret_if(!item);
324         ret_if(!part);
325
326         city_info = city_get();
327         ret_if(!city_info);
328
329         if (((double) ((int) city_info[city].timezone)) < city_info[city].timezone) {
330                 minute += 30;
331                 if (minute > 60) {
332                         hour++;
333                         minute -= 60;
334                 }
335         }
336
337         snprintf(time_result, sizeof(time_result), "%d:%d", hour, minute);
338         elm_object_part_text_set(item, part, time_result);
339 }
340
341 static void _resize_graph_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
342 {
343         result_info_s *result_info = NULL;
344         int x, y, w, h;
345         int start_x = 0;
346
347         result_info = evas_object_data_get(obj, DATA_KEY_RESULT);
348         ret_if(!result_info);
349
350         edje_object_part_geometry_get(_EDJ(obj), "graph_base", &x, &y, &w, &h);
351
352         if (result_info->start > result_info->end) {
353                 evas_object_move(result_info->rect2, x, y);
354                 evas_object_resize(result_info->rect2, w / 10.0, h);
355                 evas_object_color_set(result_info->rect2, 0, 0, 0, 255);
356                 evas_object_show(result_info->rect2);
357         } else {
358                 evas_object_hide(result_info->rect2);
359         }
360
361         start_x = (result_info->start / 24.0f) * w + x;
362
363         evas_object_move(result_info->rect1, start_x, y);
364         evas_object_resize(result_info->rect1, x + w - start_x, h);
365         evas_object_color_set(result_info->rect1, 0, 0, 0, 255);
366         evas_object_show(result_info->rect1);
367 }
368
369 static void _item_result_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
370 {
371         item_destroy_result(obj);
372 }
373
374 Evas_Object *item_create_result(Evas_Object *parent, int city, int color, int start, int end, struct tm *global_time)
375 {
376         Evas_Object *item = NULL;
377         city_s *city_info = NULL;
378         result_info_s *result_info = NULL;
379         Evas *e = NULL;
380
381         char *path = NULL;
382         char full_path[PATH_LEN] = {0, };
383         char city_str[PATH_LEN] = {0, };
384         char color_str[16] = {0, };
385
386         retv_if(!parent, NULL);
387
388         path = app_get_resource_path();
389         retv_if(!path, NULL);
390
391         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
392         free(path);
393
394         result_info = calloc(1, sizeof(result_info_s));
395         retv_if(!result_info, NULL);
396
397         item = elm_layout_add(parent);
398         goto_if(!item, error);
399
400         elm_layout_file_set(item, full_path, "item_result");
401
402         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
403         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
404         evas_object_data_set(item, DATA_KEY_RESULT, result_info);
405         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_result_del_cb, NULL);
406         //evas_object_event_callback_add(item, EVAS_CALLBACK_RESIZE, _resize_graph_cb, result_info);
407         //evas_object_event_callback_add(item, EVAS_CALLBACK_MOVE, _resize_graph_cb, result_info);
408         evas_object_show(item);
409
410         city_info = city_get();
411         goto_if(!city_info, error);
412
413         snprintf(city_str, sizeof(city_str), "%s, %s", city_info[city].name, city_info[city].nation);
414         elm_object_part_text_set(item, "city", city_str);
415
416         snprintf(color_str, sizeof(color_str), "%d", color);
417         elm_object_signal_emit(item, color_str, "mark");
418
419         _text_set_local_time(item, "time", city, global_time);
420
421         e = evas_object_evas_get(item);
422         goto_if(!e, error);
423
424         result_info->rect1 = evas_object_rectangle_add(e);
425         goto_if(!result_info->rect1, error);
426
427         result_info->rect2 = evas_object_rectangle_add(e);
428         goto_if(!result_info->rect2, error);
429
430         result_info->city = city;
431         result_info->start = start;
432         result_info->end = end;
433
434         return item;
435
436 error:
437         if (result_info) {
438                 if (result_info->rect1)
439                         evas_object_del(result_info->rect1);
440                 if (result_info->rect2)
441                         evas_object_del(result_info->rect2);
442                 free(result_info);
443         }
444
445         if (item)
446                 evas_object_del(item);
447
448         free(result_info);
449         return NULL;
450 }
451
452 void item_destroy_result(Evas_Object *item)
453 {
454         result_info_s *result_info = NULL;
455
456         ret_if(!item);
457
458         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_result_del_cb);
459
460         result_info = evas_object_data_del(item, DATA_KEY_RESULT);
461         if (result_info) {
462                 if (result_info->rect1)
463                         evas_object_del(result_info->rect1);
464                 if (result_info->rect2)
465                         evas_object_del(result_info->rect2);
466                 free(result_info);
467         }
468
469         evas_object_del(item);
470 }
471
472 static void _item_group_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
473 {
474         item_destroy_group(obj);
475 }
476
477 static void _item_group_down_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
478 {
479         _D("An item is down");
480 }
481
482 static void _item_group_up_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
483 {
484         Evas_Object *item = obj;
485         Evas_Object *selecting_item = NULL;
486         main_view_s *main_view_info = data;
487         int city = 0;
488         int count = 0;
489
490         ret_if(!item);
491         ret_if(!main_view_info);
492         ret_if(!main_view_info->city_list);
493
494         _D("An item is selected");
495
496         count = scroller_count_item(main_view_info->city_list);
497         if (count >= MAXIMUM_SELECTED_CITY) {
498                 Evas_Object *popup = NULL;
499                 _D("Cities selected are limited.");
500                 popup = popup_create_text(main_view_info->main_view, "Maximum number of cities reached");
501                 elm_object_part_content_set(main_view_info->main_view, "popup", popup);
502                 return;
503         }
504
505         city = (int) evas_object_data_get(item, DATA_KEY_CITY);
506         selecting_item = item_create_selecting(main_view_info->city_list, city, 0, main_view_info);
507         ret_if(!selecting_item);
508
509         scroller_append_item(main_view_info->city_list, selecting_item);
510 }
511
512 Evas_Object *item_create_group(Evas_Object *parent, const char *title, main_view_s *main_view_info)
513 {
514         Evas_Object *item = NULL;
515
516         char *path = NULL;
517         char full_path[PATH_LEN] = {0, };
518
519         retv_if(!parent, NULL);
520
521         path = app_get_resource_path();
522         retv_if(!path, NULL);
523
524         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
525         free(path);
526
527         item = elm_layout_add(parent);
528         retv_if(!item, NULL);
529
530         elm_layout_file_set(item, full_path, "item_group");
531
532         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
533         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
534         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_group_del_cb, NULL);
535         elm_object_signal_callback_add(item, "down", "item", _item_group_down_cb, NULL);
536         elm_object_signal_callback_add(item, "up", "item", _item_group_up_cb, main_view_info);
537
538         evas_object_show(item);
539
540         elm_object_part_text_set(item, "city", title);
541
542         return item;
543 }
544
545 void item_destroy_group(Evas_Object *item)
546 {
547         ret_if(!item);
548
549         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_group_del_cb);
550         elm_object_signal_callback_del(item, "down", "item", _item_group_down_cb);
551         elm_object_signal_callback_del(item, "up", "item", _item_group_up_cb);
552
553         evas_object_del(item);
554 }
555
556 static void _item_padding_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
557 {
558         item_destroy_padding(obj);
559 }
560
561 Evas_Object *item_create_padding(Evas_Object *parent)
562 {
563         Evas_Object *item = NULL;
564         city_s *city_info = NULL;
565
566         char *path = NULL;
567         char full_path[PATH_LEN] = {0, };
568         char city_str[PATH_LEN] = {0, };
569
570         retv_if(!parent, NULL);
571
572         path = app_get_resource_path();
573         retv_if(!path, NULL);
574
575         snprintf(full_path, sizeof(full_path), "%s/edje/%s", path, ITEM_EDJE);
576         free(path);
577
578         item = elm_layout_add(parent);
579         retv_if(!item, NULL);
580
581         elm_layout_file_set(item, full_path, "item_padding");
582
583         evas_object_size_hint_weight_set(item, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
584         evas_object_size_hint_align_set(item, EVAS_HINT_FILL, EVAS_HINT_FILL);
585         evas_object_event_callback_add(item, EVAS_CALLBACK_DEL, _item_padding_del_cb, NULL);
586
587         evas_object_show(item);
588
589         return item;
590 }
591
592 void item_destroy_padding(Evas_Object *item)
593 {
594         ret_if(!item);
595         evas_object_event_callback_del(item, EVAS_CALLBACK_DEL, _item_padding_del_cb);
596         evas_object_del(item);
597 }
598