Convert c to cpp except for ug files.
[profile/tv/apps/native/settings.git] / src / view_system_clock.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <utilX.h>
18
19 #include "dbg.h"
20 #include "def.h"
21 #include "stdbool.h"
22 #include "viewmgr.h"
23 #include "utils.h"
24 #include "data_wrapper.h"
25 #include "settings_provider.h"
26 #include "view_system_clock.h"
27
28 #define DATA_ID "system_clock_data"
29 #define MAX_ITEMS 2
30 #define ITEM_HEIGHT 82
31 #define POS_ADJUST (39 * 2)
32 #define ITEMID "itemdata"
33 #define CLOCK_ITEM 0
34 #define MANUAL "1"
35
36 #define SUBLIST_WIDTH 310.0
37 #define LEFT_MARGIN 70.0
38 #define LEFT_OFFSET (SUBLIST_WIDTH + LEFT_MARGIN)
39
40 #define SIG_DISMISSED "dismissed"
41 #define SIG_FOCUSED "focused"
42 #define SIG_UNFOCUSED "unfocused"
43 #define SIG_CLICKED "clicked"
44
45 struct _sysclk_data {
46         Evas_Object *win;
47         Evas_Object *base;
48         Evas_Object *ctxpopup;
49         Evas_Object *box;
50         Eina_Array *array;
51
52         int count;
53         int sel_idx;
54         struct settingview_data *vdata;
55         struct setting_mgr *mgr;
56
57         struct evas_obj_data ugd;
58         struct obj_geometry_data *ogd;
59 };
60
61 static void _destroy(Evas_Object *base);
62 static void _hide(Evas_Object *base);
63
64 /**
65 * Exit system clock sublist view.
66 *
67 * @param[in]: data : the user data of system clock sublist view.
68 *
69 * @return: void.
70 */
71 static void _exit_view(struct _sysclk_data *data)
72 {
73         if (!data || !data->base)
74                 return;
75
76         _hide(data->base);
77
78         settingmgr_view_pop(data->mgr);
79 }
80
81 /**
82 * Get item list.
83 *
84 * @param[in]: vdata : view data.
85 * @param[out]: count : number of item.
86 *
87 * @return: eina list containing items or null if error occurred.
88 */
89 static Eina_List *_get_item_list(struct settingview_data *vdata, int *count)
90 {
91         Eina_List *list;
92
93         if (!vdata || !count) {
94                 _ERR("Invalid arguments");
95                 return NULL;
96         }
97
98         list = settingitem_get_data_list(viewdata_get_parentitem(vdata));
99         if (!list) {
100                 *count = 0;
101                 return NULL;
102         }
103
104         *count = eina_list_count(list);
105
106         return list;
107 }
108
109 /**
110 * Get selected value: Manual or Auto.
111 *
112 * @param[in]: data : the user data of system clock sublist view.
113 *
114 * @return: the selected value or null if error occurred.
115 */
116 static char *_get_selected_value(struct _sysclk_data *data)
117 {
118         struct settingitem *item;
119
120         if (!data || !data->vdata) {
121                 _ERR("Invalid argument");
122                 return NULL;
123         }
124
125         item = viewdata_get_parentitem(data->vdata);
126         if (!item) {
127                 _ERR("Get item failed");
128                 return NULL;
129         }
130
131         return provider_get_list_value(item);
132 }
133
134 /**
135 * Set selected value: Manual or Auto.
136 *
137 * @param[in]: data : the user data of system clock sublist view.
138 * @param[in]: obj : the selected object.
139 *
140 * @return: void.
141 */
142 static void _set_selected_value(struct _sysclk_data *data, Evas_Object *obj)
143 {
144         struct settingitem *item;
145         char *selval;
146         int ret;
147
148         if (!data || !data->vdata || !obj) {
149                 _ERR("Invalid argument");
150                 return;
151         }
152
153         item = viewdata_get_parentitem(data->vdata);
154         if (!item) {
155                 _ERR("Get item failed");
156                 return;
157         }
158
159         selval = (char *) evas_object_data_get(obj, ITEMID);
160         if (selval) {
161                 ret = provider_set_list_value(item, selval);
162                 if (ret != 0)
163                         _ERR("Set list value failed");
164         }
165 }
166
167 /**
168 * Evas_Smart_Cb type callback for handling foucs in event.
169 *
170 * @param[in]: priv : the user data.
171 * @param[in]: obj : the corresponding object which the foucs in event occurred.
172 * @param[in]: ev : event info.
173 *
174 * @return: void.
175 */
176 static void _subitem_focusin_cb(void *priv, Evas_Object *obj, void *ev)
177 {
178         struct _sysclk_data *data;
179         char *value;
180         char *selval;
181
182         if (!obj || !priv) {
183                 _ERR("Invalid arguments\n");
184                 return;
185         }
186
187         data = (struct _sysclk_data *) priv;
188
189         value = (char *) evas_object_data_get(obj, ITEMID);
190         if (!value) {
191                 _ERR("Get value from btn failed\n");
192                 return;
193         }
194
195         selval = _get_selected_value(data);
196         if (!selval) {
197                 _ERR("_get_selected_value failed\n");
198                 return;
199         }
200
201         if (!strncmp(selval, value, strlen(selval))) {
202                 elm_object_signal_emit(obj, CTXPOPUPBTN_ICON_FOCUSED,
203                                 CTXPOPUPBTN_ICON_SOURCE);
204         }
205
206         elm_object_signal_emit(obj, CTXPOPUPBTN_BUTTON_FOCUSED,
207                         CTXPOPUPBTN_BUTTON_SOURCE);
208
209         provider_release_list_value(selval);
210 }
211
212 /**
213 * Evas_Smart_Cb type callback for handling focus out event.
214 *
215 * @param[in]: priv : the user data.
216 * @param[in]: obj : the corresponding object which the focus out event occurred.
217 * @param[in]: ev : event info.
218 *
219 * @return: void.
220 */
221 static void _subitem_focusout_cb(void *priv, Evas_Object *obj, void *ev)
222 {
223         struct _sysclk_data *data;
224         char *value;
225         char *selval;
226
227         if (!obj || !priv) {
228                 _ERR("Invalid arguments\n");
229                 return;
230         }
231
232         data = (struct _sysclk_data *) priv;
233
234         value = (char *) evas_object_data_get(obj, ITEMID);
235         if (!value) {
236                 _ERR("Get value from btn failed\n");
237                 return;
238         }
239
240         selval = _get_selected_value(data);
241         if (!selval) {
242                 _ERR("_get_selected_value failed\n");
243                 return;
244         }
245
246         if (!strncmp(selval, value, strlen(selval)))
247                 elm_object_signal_emit(obj, CTXPOPUPBTN_BUTTON_HIGHLIGHT,
248                                 CTXPOPUPBTN_BUTTON_SOURCE);
249         else
250                 elm_object_signal_emit(obj, CTXPOPUPBTN_BUTTON_UNFOCUSED,
251                                 CTXPOPUPBTN_BUTTON_SOURCE);
252
253         provider_release_list_value(selval);
254 }
255
256 /**
257 * Evas_Smart_Cb type callback for handling click event.
258 *
259 * @param[in]: priv : the user data.
260 * @param[in]: obj : the corresponding object which the click event occurred.
261 * @param[in]: ev : event info.
262 *
263 * @return: void.
264 */
265 static void _subitem_clicked_cb(void *priv, Evas_Object *obj, void *ev)
266 {
267         struct _sysclk_data *data;
268         struct settingitem *item;
269         Eina_List *list;
270         char *value;
271         const char *id;
272         const char *name;
273
274         if (!priv || !obj)
275                 return;
276
277         data = (struct _sysclk_data *) priv;
278
279         _set_selected_value(data, obj);
280
281         value = (char *) evas_object_data_get(obj, ITEMID);
282         if (!value) {
283                 _ERR("get value from obj failed. DATA_ID: %s", ITEMID);
284                 return;
285         }
286
287         if (!strncmp(value, MANUAL, BUF_SIZE)) {
288                 _hide(data->base);
289
290                 list = viewdata_get_childitems_list(data->vdata);
291                 if (!list) {
292                         _ERR("list of clock is null.");
293                         return;
294                 }
295
296                 item = (struct settingitem *) eina_list_nth(list, CLOCK_ITEM);
297                 if (!item) {
298                         _ERR("there is no clock_mode item in list.");
299                         return;
300                 }
301
302                 id = settingitem_get_id(item);
303                 if (!id) {
304                         _ERR("get item id failed.");
305                         return;
306                 }
307
308                 name = settingitem_get_display_name(item);
309                 if (!name) {
310                         _ERR("get display_name failed.");
311                         return;
312                 }
313
314                 data->ugd.display_name = name;
315
316                 settingmgr_view_push(data->mgr, id, (void *)&data->ugd);
317         } else {
318                 _exit_view(data);
319         }
320 }
321
322 /**
323 * Evas_Object_Event_Cb type callback for handling key press event.
324 *
325 * @param[in]: priv : the user data.
326 * @param[in]: e : the evas canvas.
327 * @param[in]: obj : the corresponding object which the key press event occurred.
328 * @param[in]: ei : event info.
329 *
330 * @return: void.
331 */
332 static void _subitem_keypress_cb(void *priv, Evas *e,
333                 Evas_Object *obj, void *ei)
334 {
335         Evas_Event_Key_Down *ev;
336         struct _sysclk_data *data;
337
338         if (!priv || !ei)
339                 return;
340
341         data = (struct _sysclk_data *) priv;
342         ev = (Evas_Event_Key_Down *) ei;
343
344         if (!ev->keyname)
345                 return;
346
347         if (!strncmp(ev->keyname, KEY_BACK, BUF_SIZE) || !strncmp(ev->keyname, KEY_BACK_REMOTE, BUF_SIZE))
348                 _exit_view(data);
349 }
350
351 /**
352 * Create system clock sublist items.
353 *
354 * @param[in]: data : the user data.
355 * @param[in]: list : the eina list containing items.
356 * @param[in]: selval : the current selected value of item.
357 *
358 * @return: 0 - Success, -1 - Fail.
359 */
360 static int _add_sysclk_sublist_item(struct _sysclk_data *data,
361                 Eina_List *list, const char *selval)
362 {
363         Evas_Object *box, *cp, *btn, *del_btn;
364         Eina_Array *array;
365         Eina_Array_Iterator aiter;
366         struct listitem *li;
367         void* obj;
368         Eina_List *iter;
369         const char *disp, *value;
370         int idx, i, j;
371
372         if (!data || !list || !data->ctxpopup || !selval) {
373                 _ERR("invalid arguments.");
374                 return -1;
375         }
376
377         cp = data->ctxpopup;
378
379         box = utils_add_box(cp);
380         if (!box) {
381                 _ERR("utils add box to ctxpopup failed.");
382                 return -1;
383         }
384
385         elm_object_content_set(cp, box);
386
387         array = eina_array_new(1);
388         if (!array) {
389                 _ERR("eina array new failed.");
390                 evas_object_del(box);
391                 return -1;
392         }
393
394         i = idx = 0;
395         EINA_LIST_FOREACH(list, iter, obj) {
396                 li = (struct listitem *) obj;
397                 disp = listitem_get_display_name(li);
398                 if (!disp) {
399                         _ERR("display name of list item is null.");
400                         goto error;
401                 }
402
403                 btn = utils_add_btn(box, (char *) CTXPOPUPBTN_STYLE, disp, EINA_TRUE);
404                 if (!btn) {
405                         _ERR("utils add button failed.");
406                         goto error;
407                 }
408
409                 value = listitem_get_value(li);
410                 if (!value) {
411                         _ERR("value of this list item is null.");
412                         goto error;
413                 }
414
415                 if (!strncmp(selval, value, strlen(selval))) {
416                         elm_object_signal_emit(btn,
417                                         CTXPOPUPBTN_BUTTON_HIGHLIGHT,
418                                         CTXPOPUPBTN_BUTTON_SOURCE);
419                         idx = i;
420                 }
421
422                 evas_object_data_set(btn, ITEMID, value);
423
424                 evas_object_smart_callback_add(btn, SIG_FOCUSED,
425                                 _subitem_focusin_cb, data);
426                 evas_object_smart_callback_add(btn, SIG_UNFOCUSED,
427                                 _subitem_focusout_cb, data);
428                 evas_object_smart_callback_add(btn, SIG_CLICKED,
429                                 _subitem_clicked_cb, data);
430                 evas_object_event_callback_add(btn, EVAS_CALLBACK_KEY_DOWN,
431                                 _subitem_keypress_cb, data);
432
433                 elm_box_pack_end(box, btn);
434                 eina_array_push(array, btn);
435
436                 if (i == 0)
437                         elm_object_focus_set(btn, EINA_TRUE);
438
439                 i++;
440         }
441
442         data->box = box;
443         data->array = array;
444         data->sel_idx = idx;
445
446         return 0;
447
448 error:
449         EINA_ARRAY_ITER_NEXT(array, j, obj, aiter) {
450                 del_btn = (Evas_Object *) obj;
451                 if (del_btn)
452                         evas_object_del(del_btn);
453         }
454
455         evas_object_del(box);
456         eina_array_free(array);
457
458         return -1;
459 }
460
461 /**
462 * Create system clock sublist view.
463 *
464 * @param[in]: data : the user data.
465 *
466 * @return: 0 - Success, -1 - Fail.
467 */
468 static int _draw_sysclk_sublist(struct _sysclk_data *data)
469 {
470         Evas_Object *ctxpopup;
471         char *selval;
472         struct settingview_data *vdata;
473         struct obj_geometry_data *ogd;
474         Eina_List *itlist;
475         int xpos, ypos, height, count, r;
476         double ratio;
477
478         if (!data || !data->ctxpopup || !data->ogd || !data->vdata) {
479                 _ERR("Invalid argument\n");
480                 return -1;
481         }
482
483         ctxpopup = data->ctxpopup;
484         vdata = data->vdata;
485         ogd = data->ogd;
486
487         count = 0;
488         itlist = _get_item_list(vdata, &count);
489         if (!itlist) {
490                 _ERR("Get item list failed");
491                 return -1;
492         }
493
494         data->count = count;
495
496         selval = _get_selected_value(data);
497         if (!selval) {
498                 _ERR("Get selected value failed");
499                 return -1;
500         }
501
502         if (count > MAX_ITEMS) {
503                 _ERR("system clock sublist is too many.");
504                 goto error;
505         }
506
507         r = _add_sysclk_sublist_item(data, itlist, selval);
508         if (r != 0) {
509                 _ERR("add system clock sublist items failed.");
510                 goto error;
511         }
512
513         if (ogd->width <= 0) {
514                 _ERR("width of object is less than 0.");
515                 goto error;
516         }
517
518         ratio = (ogd->width - LEFT_OFFSET) / ogd->width;
519         xpos = ogd->x + ogd->width * ratio;
520         ypos = ogd->y;
521
522         height = data->count * ITEM_HEIGHT;
523
524         if (ypos > WIN_HEIGHT)
525                 ypos = ypos - height;
526
527         evas_object_move(ctxpopup, xpos * ELM_SCALE, ypos * ELM_SCALE);
528
529         utils_set_focus_directions(data->array, data->count);
530
531         provider_release_list_value(selval);
532
533         return 0;
534
535 error:
536         provider_release_list_value(selval);
537         return -1;
538 }
539
540 /**
541 * Evas_Smart_Cb type callback for handling ctxpopup dismissed event.
542 *
543 * @param[in]: priv : the user data.
544 * @param[in]: obj : the corresponding object which the dismissed event occurred.
545 * @param[in]: ev : event info.
546 *
547 * @return: void.
548 */
549 static void _ctxpopup_dismissed(void *priv, Evas_Object *obj,
550                 void *ev)
551 {
552         struct _sysclk_data *data;
553
554         if (!priv || !obj)
555                 return;
556
557         data = (struct _sysclk_data *) priv;
558
559         _hide(data->base);
560
561         settingmgr_view_pop(data->mgr);
562 }
563
564 /**
565 * Create all the UI components of system clock sublist view.
566 *
567 * @param[in]: mgr : view manager of settings views.
568 * @param[in]: view : data of view.
569 * @param[in]: prev : the user data.
570 *
571 * @return: the base layout of system clock view or null
572 *              if error occurred.
573 */
574 static Evas_Object *_create(struct setting_mgr *mgr,
575                 struct settingview_data *view, void *prev)
576 {
577         Evas_Object *base;
578         Evas_Object *ctxpopup;
579         Evas_Object *win;
580         struct _sysclk_data *data;
581         struct evas_obj_data *ugd;
582         struct obj_geometry_data *ogd;
583
584         if (!mgr || !view || !prev) {
585                 _ERR("Invalid argument!\n");
586                 return NULL;
587         }
588
589         ugd = (struct evas_obj_data *) prev;
590         ogd = (struct obj_geometry_data *) evas_object_data_get(ugd->cur_btn, DATA_ID);
591
592         win = settingmgr_get_win(mgr);
593         if (!win) {
594                 _ERR("settingmgr get window failed.");
595                 return NULL;
596         }
597
598         data = (struct _sysclk_data *) calloc(1, sizeof(*data));
599         if (!data) {
600                 _ERR("Unable to allocate memory.");
601                 return NULL;
602         }
603
604         data->ugd = *ugd;
605
606         base = elm_layout_add(win);
607         if (!base) {
608                 free(data);
609                 return NULL;
610         }
611
612         elm_layout_file_set(base, EDJ_FILE, SUBLIST_VIEW_PAGE);
613
614         ctxpopup = utils_add_ctxpopup(win, (char *) SUBLIST_CTXPOPUP_STYLE1);
615         if (!ctxpopup) {
616                 _ERR("Fail to add ctxpopup");
617                 evas_object_del(base);
618                 free(data);
619                 return NULL;
620         }
621
622         evas_object_smart_callback_add(ctxpopup, SIG_DISMISSED,
623                         _ctxpopup_dismissed, data);
624
625         data->mgr = mgr;
626         data->win = win;
627         data->base = base;
628         data->ctxpopup = ctxpopup;
629         data->vdata = view;
630         data->ogd = ogd;
631
632         evas_object_data_set(base, DATA_ID, data);
633
634         if (_draw_sysclk_sublist(data) == -1) {
635                 _ERR("Error in drawing items function\n");
636                 evas_object_del(base);
637                 evas_object_del(ctxpopup);
638                 free(data);
639                 return NULL;
640         }
641
642         return base;
643 }
644
645 /**
646 * Show the system clock view.
647 *
648 * @param[in]: base : the base layout of system clock view.
649 *
650 * @return: void.
651 */
652 static void _show(Evas_Object *base)
653 {
654         struct _sysclk_data *data;
655
656         if (!base) {
657                 _ERR("Invalid argument\n");
658                 return;
659         }
660
661         data = (struct _sysclk_data *) evas_object_data_get(base, DATA_ID);
662         if (!data) {
663                 _ERR("Get sublist data failed\n");
664                 return;
665         }
666
667         evas_object_show(data->ctxpopup);
668         evas_object_show(base);
669 }
670
671 /**
672 * Destroy the system clock view.
673 *
674 * @param[in]: base : the base layout of system clock view.
675 *
676 * @return: void.
677 */
678 static void _destroy(Evas_Object *base)
679 {
680         struct _sysclk_data *data;
681
682         if (!base)
683                 return;
684
685         data = (struct _sysclk_data *)evas_object_data_get(base, DATA_ID);
686         if (!data) {
687                 _ERR("Invalid arguments");
688                 evas_object_del(data->ctxpopup);
689                 evas_object_del(base);
690                 return;
691         }
692
693         if (data->array) {
694                 eina_array_free(data->array);
695                 data->array = NULL;
696         }
697
698         evas_object_del(data->ctxpopup);
699         evas_object_del(base);
700
701         if (data->vdata)
702                 viewdata_release(data->vdata);
703
704         free(data);
705 }
706
707 /**
708 * Hide the system clock view.
709 *
710 * @param[in]: base : the base layout of system clock view.
711 *
712 * @return: void.
713 */
714 static void _hide(Evas_Object *base)
715 {
716         struct _sysclk_data *data;
717
718         if (!base)
719                 return;
720
721         data = (struct _sysclk_data *)evas_object_data_get(base, DATA_ID);
722         if (!data) {
723                 _ERR("Invalid arguments");
724                 return;
725         }
726
727         evas_object_hide(base);
728         evas_object_hide(data->ctxpopup);
729 }
730
731 /**
732 * Refresh Manual/Auto text of system clock item.
733 *
734 * @param[in]: base : the base layout of system clock view.
735 *
736 * @return: void.
737 */
738 static void _refresh(Evas_Object *base)
739 {
740         struct _sysclk_data *data;
741
742         if (!base) {
743                 _ERR("the base of system clock is null.");
744                 return;
745         }
746
747         data = (struct _sysclk_data *)evas_object_data_get(base, DATA_ID);
748         if (!data) {
749                 _ERR("data get failed. DATA_ID: %s", DATA_ID);
750                 return;
751         }
752
753         _exit_view(data);
754 }
755
756 /**
757 * view class of system clock view.
758 */
759 static struct setting_class _vclass = {
760         VCLASS_TITLE_SYSTEM_CLOCK,
761         _create,
762         _show,
763         NULL,
764         NULL,
765         _refresh,
766         NULL,
767         _hide,
768         _destroy,
769         NULL,
770         NULL,
771         NULL,
772         0
773 };
774
775 /**
776 * Return view class of system clock view.
777 *
778 * @param: void.
779 *
780 * @return: the view class of system clock view.
781 */
782 struct setting_class *view_system_clock_get_vclass(void)
783 {
784         return &_vclass;
785 }