add user delete button and delete popup
[profile/tv/apps/native/air_home.git] / src / view / view_user_edit.c
1 /*
2
3  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4  *
5  * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
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
18 #include <Elementary.h>
19 #include <app_debug.h>
20 #include <viewmgr.h>
21 #include <inputmgr.h>
22
23 #include "defs.h"
24 #include "view_user_edit.h"
25 #include "view_photo.h"
26 #include "datamgr.h"
27 #include "utils.h"
28
29 #define MESSAGE_BTN_DONE "Done"
30 #define MESSAGE_BTN_CANCEL "Cancel"
31 #define MESSAGE_ADD_USER "Add user"
32 #define MESSAGE_EDIT_USER "Edit user"
33 #define MESSAGE_DELETE_USER "Delete user"
34 #define MESSAGE_DELETE_CONTENTS "If you delete this user, their data will also be deleted."
35 #define MESSAGE_DELETE "Delete"
36 #define MESSAGE_CANCEL "Cancel"
37
38 #define MESSAGE_ENTRY_NAME "User Name"
39 #define MESSAGE_ENTRY_ACCOUNT "sample@tizen.com"
40 #define MESSAGE_ENTRY_PIN "Pin code"
41 #define ICON_ADD "add"
42 #define KEY_ICON "icon"
43 #define KEY_FOCUS_ICON "focusicon"
44
45 #define CTXPOPUP_X 294
46 #define CTXPOPUP_Y 310
47 #define MAX_BUF 128
48
49 struct _icon_info {
50         const char *file;
51         const char *focus_file;
52         const char *message;
53         const char *focus_message;
54 };
55
56 struct _priv {
57         Evas_Object *win;
58         Evas_Object *base;
59         Evas_Object *ly;
60         Evas_Object *photo;
61         Evas_Object *name;
62         Evas_Object *account;
63         Evas_Object *pin;
64         Evas_Object *lock;
65         Evas_Object *icon;
66         Evas_Object *focus_icon;
67         Evas_Object *done;
68         Evas_Object *cancel;
69         Evas_Object *ctxpopup;
70         Evas_Object *del;
71         Evas_Object *popup;
72
73         struct datamgr *dm;
74 };
75
76 static void _done_key_down(int id, void *data, Evas *e, Evas_Object *obj,
77                 Evas_Event_Key_Down *ev)
78 {
79         if (!strcmp(ev->keyname, KEY_ENTER)) {
80                 /* check state of user edit */
81                 viewmgr_pop_view();
82         }
83 }
84
85 static input_handler done_handler = {
86         .key_down = _done_key_down
87 };
88
89 static void _cancel_key_down(int id, void *data, Evas *e, Evas_Object *obj,
90                 Evas_Event_Key_Down *ev)
91 {
92         if (!strcmp(ev->keyname, KEY_ENTER)) {
93                 viewmgr_pop_view();
94         }
95 }
96
97 static input_handler cancel_handler = {
98         .key_down = _cancel_key_down
99 };
100
101 static bool _add_btns(struct _priv *priv)
102 {
103         Evas_Object *done, *cancel;
104
105         done = utils_add_button(priv->base, MESSAGE_BTN_DONE,
106                         PART_USER_EDIT_BTN_DONE);
107         if (!done) {
108                 _ERR("failed to add done btn");
109                 return false;
110         }
111         inputmgr_add_callback(done, 0, &done_handler, NULL);
112
113         cancel = utils_add_button(priv->base, MESSAGE_BTN_CANCEL,
114                         PART_USER_EDIT_BTN_CANCEL);
115         if (!cancel) {
116                 _ERR("failed to add cancel btn");
117                 evas_object_del(done);
118                 return false;
119         }
120         inputmgr_add_callback(cancel, 0, &cancel_handler, NULL);
121
122         priv->cancel = cancel;
123         priv->done = done;
124
125         return true;
126 }
127
128 static void _focused(int id, void *data, Evas_Object *obj,
129                 Elm_Object_Item *item)
130 {
131         elm_object_signal_emit(obj, SIG_FOCUS, SRC_PROG);
132 }
133
134 static void _unfocused(int id, void *data, Evas_Object *obj,
135                 Elm_Object_Item *item)
136 {
137         elm_object_signal_emit(obj, SIG_UNFOCUS, SRC_PROG);
138 }
139
140 static void _load_user_icon(struct _priv *priv, const char *file,
141                 const char *focus_file)
142 {
143         Evas_Object *icon, *focus_icon;
144
145         icon = utils_add_icon(priv->photo, file, PART_USER_EDIT_PHOTO);
146         if (!icon)
147                 _ERR("failed to add icon");
148
149         focus_icon = utils_add_icon(priv->photo, focus_file,
150                         PART_USER_EDIT_PHOTO_FOCUS);
151         if (!focus_icon)
152                 _ERR("failed to add focus icon");
153
154         priv->icon = icon;
155         priv->focus_icon = focus_icon;
156 }
157
158 static void _eo_key_down(int id, void *data, Evas *e, Evas_Object *obj,
159                 Evas_Event_Key_Down *ev)
160 {
161         struct _priv *priv;
162         const char *file, *focus_file;
163
164         if (!data)
165                 return;
166
167         priv = data;
168
169         if (!strcmp(ev->keyname, KEY_BACK) ||
170                         !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
171                 evas_object_del(priv->ctxpopup);
172                 priv->ctxpopup = NULL;
173         } else if (!strcmp(ev->keyname, KEY_ENTER) ||
174                         !strcmp(ev->keyname, KEY_ENTER_REMOTE)) {
175                 evas_object_del(priv->ctxpopup);
176                 priv->ctxpopup = NULL;
177
178                 file = evas_object_data_get(obj, KEY_ICON);
179                 focus_file = evas_object_data_get(obj, KEY_FOCUS_ICON);
180
181                 if (!strcmp(file, ICON_ADD) || !strcmp(focus_file, ICON_ADD))
182                         viewmgr_push_view(VIEW_PHOTO);
183                 else
184                         _load_user_icon(priv, file, focus_file);
185         }
186 }
187
188 static input_handler icon_handler = {
189         .focused = _focused,
190         .unfocused = _unfocused,
191         .key_down = _eo_key_down
192 };
193
194 static Evas_Object *_pack_icon(Evas_Object *table, struct _icon_info *icon_info, int i)
195 {
196         Evas_Object *eo, *ic, *focus_ic;
197
198         eo = utils_add_layout(table, GRP_USER_EDIT_ICON_LIST_ITEM, true, NULL);
199         if (!eo) {
200                 _ERR("failed to add layout");
201                 return NULL;
202         }
203         evas_object_show(eo);
204         elm_table_pack(table, eo, i % 4, i / 4, 1, 1);
205
206         ic = utils_add_icon(eo, icon_info->file, PART_USER_EDIT_ICON_LIST_ITEM);
207         if (!ic) {
208                 _ERR("failed to add icon");
209                 evas_object_del(eo);
210                 return NULL;
211         }
212
213         focus_ic = utils_add_icon(eo, icon_info->focus_file,
214                         PART_USER_EDIT_ICON_LIST_ITEM_FOCUS);
215         if (!focus_ic) {
216                 _ERR("failed to add focus icon");
217                 evas_object_del(eo);
218                 return NULL;
219         }
220         evas_object_data_set(eo, KEY_ICON, icon_info->message);
221         evas_object_data_set(eo, KEY_FOCUS_ICON, icon_info->focus_message);
222
223         return eo;
224 }
225
226 static void _add_icon_list(struct _priv *priv)
227 {
228         Evas_Coord x, y, w, h;
229         Evas_Object *ctxpopup, *ly, *table, *eo;
230         int i;
231         struct _icon_info icon_info[] = {
232                 {
233                         IMAGE_USER_DEFAULT,
234                         IMAGE_USER_DEFAULT_FOCUS,
235                         IMAGE_USER_CURRENT_DEFAULT,
236                         IMAGE_USER_CURRENT_DEFAULT_FOCUS
237                 },
238                 {
239                         IMAGE_USER_DEFAULT_02,
240                         IMAGE_USER_DEFAULT_02_FOCUS,
241                         IMAGE_USER_CURRENT_DEFAULT_02,
242                         IMAGE_USER_CURRENT_DEFAULT_02_FOCUS
243                 },
244                 {
245                         IMAGE_USER_DEFAULT_03,
246                         IMAGE_USER_DEFAULT_03_FOCUS,
247                         IMAGE_USER_CURRENT_DEFAULT_03,
248                         IMAGE_USER_CURRENT_DEFAULT_03_FOCUS
249                 },
250                 {
251                         IMAGE_USER_DEFAULT_04,
252                         IMAGE_USER_DEFAULT_04_FOCUS,
253                         IMAGE_USER_CURRENT_DEFAULT_04,
254                         IMAGE_USER_CURRENT_DEFAULT_04_FOCUS
255                 },
256                 {
257                         IMAGE_USER_DEFAULT_05,
258                         IMAGE_USER_DEFAULT_05_FOCUS,
259                         IMAGE_USER_CURRENT_DEFAULT_05,
260                         IMAGE_USER_CURRENT_DEFAULT_05_FOCUS
261                 },
262                 {
263                         IMAGE_USER_DEFAULT_06,
264                         IMAGE_USER_DEFAULT_06_FOCUS,
265                         IMAGE_USER_CURRENT_DEFAULT_06,
266                         IMAGE_USER_CURRENT_DEFAULT_06_FOCUS
267                 },
268                 {
269                         IMAGE_USER_DEFAULT_07,
270                         IMAGE_USER_DEFAULT_07_FOCUS,
271                         IMAGE_USER_CURRENT_DEFAULT_07,
272                         IMAGE_USER_CURRENT_DEFAULT_07_FOCUS
273                 },
274                 {
275                         IMAGE_USER_ADD,
276                         IMAGE_USER_ADD_FOCUS,
277                         ICON_ADD,
278                         ICON_ADD
279                 }
280         };
281
282         ctxpopup = elm_ctxpopup_add(priv->base);
283         if (!ctxpopup) {
284                 _ERR("failed to add ctxpopup");
285                 return;
286         }
287         elm_ctxpopup_horizontal_set(ctxpopup, EINA_TRUE);
288         elm_ctxpopup_auto_hide_disabled_set(ctxpopup, EINA_TRUE);
289
290         ly = utils_add_layout(ctxpopup, GRP_USER_EDIT_ICON_LIST, false, NULL);
291         if (!ly) {
292                 _ERR("failed to layout");
293                 evas_object_del(ctxpopup);
294                 return;
295         }
296         elm_object_content_set(ctxpopup, ly);
297         evas_object_show(ly);
298         evas_object_show(ctxpopup);
299
300         evas_object_geometry_get(priv->photo, &x, &y, &w, &h);
301         evas_object_move(ctxpopup,
302                         (x + w + CTXPOPUP_X) * elm_config_scale_get(),
303                         (y + CTXPOPUP_Y) * elm_config_scale_get());
304
305         table = utils_add_table(ly, true, PART_USER_EDIT_ICON_LIST);
306         if (!table) {
307                 _ERR("failed to add table");
308                 evas_object_del(ctxpopup);
309                 return;
310         }
311         elm_table_padding_set(table, elm_config_scale_get() * 1,
312                         elm_config_scale_get() * 1);
313         evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND,
314                         EVAS_HINT_EXPAND);
315
316         for (i = 0; i < sizeof(icon_info) / sizeof(*icon_info); i++) {
317                 eo = _pack_icon(table, &icon_info[i], i);
318                 if (!eo)
319                         continue;
320
321                 inputmgr_add_callback(eo, 0, &icon_handler, priv);
322                 if (i == 0)
323                         elm_object_focus_set(eo, EINA_TRUE);
324         }
325
326         priv->ctxpopup = ctxpopup;
327 }
328
329 static void _photo_key_down(int id, void *data, Evas *e, Evas_Object *obj,
330                 Evas_Event_Key_Down *ev)
331 {
332         if (!strcmp(ev->keyname, KEY_ENTER)) {
333                 _add_icon_list(data);
334         }
335 }
336
337 static input_handler photo_handler = {
338         .focused = _focused,
339         .unfocused = _unfocused,
340         .key_down = _photo_key_down
341 };
342
343 static void _load_lock_icon(struct _priv *priv, Evas_Object *ly)
344 {
345         Evas_Object *lock;
346         const char *file = NULL;
347
348         if (priv->lock) {
349                 elm_image_file_get(priv->lock, &file, NULL);
350                 elm_object_part_content_unset(priv->lock,
351                                 PART_USER_EDIT_SWITCH);
352                 evas_object_del(priv->lock);
353         }
354
355         if (!file || !strcmp(file, IMAGE_SWITCH_OFF))
356                 file = IMAGE_SWITCH_ON;
357         else
358                 file = IMAGE_SWITCH_OFF;
359         lock = utils_add_icon(ly, file, PART_USER_EDIT_SWITCH);
360
361         priv->lock = lock;
362 }
363
364 static void _lock_key_down(int id, void *data, Evas *e, Evas_Object *obj,
365                 Evas_Event_Key_Down *ev)
366 {
367         if (!strcmp(ev->keyname, KEY_ENTER))
368                 _load_lock_icon(data, obj);
369 }
370
371 static input_handler lock_handler = {
372         .focused = _focused,
373         .unfocused = _unfocused,
374         .key_down = _lock_key_down
375 };
376
377 static Evas_Object *_add_layout(struct _priv *priv)
378 {
379         Evas_Object *ly, *photo, *name, *pin, *account, *lock;
380
381         ly = utils_add_layout(priv->base, GRP_USER_EDIT_CONTENTS, false,
382                         PART_USER_EDIT_CONTENTS);
383         if (!ly) {
384                 _ERR("failed to add layout");
385                 return NULL;
386         }
387
388         photo = utils_add_layout(ly, GRP_USER_EDIT_PHOTO, true,
389                         PART_USER_EDIT_CONTENTS_PHOTO);
390         if (!photo)
391                 goto err;
392
393         name = utils_add_entry(ly, MESSAGE_ENTRY_NAME, false,
394                         PART_USER_EDIT_CONTENTS_NAME);
395         if (!name)
396                 goto err;
397
398         pin = utils_add_entry(ly, MESSAGE_ENTRY_PIN, false,
399                         PART_USER_EDIT_CONTENTS_PIN);
400         if (!pin)
401                 goto err;
402
403         account = utils_add_entry(ly, MESSAGE_ENTRY_ACCOUNT, false,
404                         PART_USER_EDIT_CONTENTS_ACCOUNT);
405         if (!account)
406                 goto err;
407
408         lock = utils_add_layout(ly, GRP_USER_EDIT_SWITCH, true,
409                         PART_USER_EDIT_CONTENTS_LOCK);
410         if (!lock)
411                 goto err;
412
413         _load_lock_icon(priv, lock);
414
415         inputmgr_add_callback(lock, 0, &lock_handler, priv);
416         inputmgr_add_callback(photo, 0, &photo_handler, priv);
417
418         priv->photo = photo;
419         priv->name = name;
420         priv->account = account;
421         priv->pin = pin;
422
423         return ly;
424 err:
425         _ERR("failed to add layout");
426         evas_object_del(ly);
427         return NULL;
428 }
429
430 static bool _add_user_edit(struct _priv *priv)
431 {
432         Evas_Object *ly;
433
434         ly = _add_layout(priv);
435         if (!ly) {
436                 _ERR("failed to add edit layout");
437                 return false;
438         }
439
440         if (!_add_btns(priv)) {
441                 _ERR("failed to add buttons");
442                 evas_object_del(ly);
443                 return false;
444         }
445
446         /* It should be implemented later about function btn */
447
448         priv->ly = ly;
449
450         return true;
451 }
452
453 static Evas_Object *_create(Evas_Object *win, void *data)
454 {
455         struct _priv *priv;
456         Evas_Object *base;
457
458         if (!win || !data) {
459                 _ERR("Invalid argument");
460                 return NULL;
461         }
462
463         priv = calloc(1, sizeof(*priv));
464         if (!priv) {
465                 _ERR("failed to calloc priv");
466                 return NULL;
467         }
468
469         base = utils_add_layout(win, GRP_USER_EDIT, false, NULL);
470         if (!base) {
471                 _ERR("failed to create base");
472                 free(priv);
473                 return NULL;
474         }
475         evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
476                         EVAS_HINT_EXPAND);
477         elm_win_resize_object_add(win, base);
478
479         priv->win = win;
480         priv->base = base;
481         priv->dm = data;
482
483         if (!_add_user_edit(priv)) {
484                 _ERR("failed to add user edit layout");
485                 evas_object_del(base);
486                 free(priv);
487                 return NULL;
488         }
489
490         viewmgr_set_view_data(VIEW_USER_EDIT, priv);
491         viewmgr_add_view(view_photo_get_vclass(), NULL);
492
493         return base;
494 }
495
496 static void _delete_user_key_down(int id, void *data, Evas *e, Evas_Object *obj,
497                 Evas_Event_Key_Down *ev)
498 {
499         struct _priv *priv;
500
501         if (!data) {
502                 _ERR("Invalid argument");
503                 return;
504         }
505
506         priv = data;
507
508         if (!strcmp(ev->keyname, KEY_ENTER) ||
509                         !strcmp(ev->keyname, KEY_ENTER_REMOTE)) {
510                 evas_object_del(priv->popup);
511                 priv->popup = NULL;
512                 /* TODO: datamgr_select_item for deleting user */
513         } else if (!strcmp(ev->keyname, KEY_BACK) ||
514                         !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
515                 evas_object_del(priv->popup);
516                 priv->popup = NULL;
517         }
518 }
519
520 static input_handler delete_user_handler = {
521         .key_down = _delete_user_key_down
522 };
523
524 static void _cancel_user_key_down(int id, void *data, Evas *e, Evas_Object *obj,
525                 Evas_Event_Key_Down *ev)
526 {
527         struct _priv *priv;
528
529         if (!data) {
530                 _ERR("Invalid argument");
531                 return;
532         }
533
534         priv = data;
535
536         if (!strcmp(ev->keyname, KEY_ENTER) ||
537                         !strcmp(ev->keyname, KEY_ENTER_REMOTE) ||
538                         !strcmp(ev->keyname, KEY_BACK) ||
539                         !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
540                 evas_object_del(priv->popup);
541                 priv->popup = NULL;
542         }
543 }
544
545 static input_handler cancel_user_handler = {
546         .key_down = _cancel_user_key_down
547 };
548
549 static void _add_delete_popup(struct _priv *priv)
550 {
551         Evas_Object *popup, *delete_btn, *cancel_btn;
552         char buf[MAX_BUF];
553
554         popup = elm_popup_add(priv->base);
555         if (!popup) {
556                 _ERR("failed to add popup");
557                 return;
558         }
559         elm_object_part_text_set(popup, PART_TITLE_TEXT, MESSAGE_DELETE_USER);
560         elm_popup_orient_set(popup, ELM_POPUP_ORIENT_CENTER);
561         evas_object_show(popup);
562         priv->popup = popup;
563
564         /* TODO: put the user name */
565         snprintf(buf, sizeof(buf), "%s %s?<br> %s", MESSAGE_DELETE,
566                         "", MESSAGE_DELETE_CONTENTS);
567         elm_object_text_set(popup, buf);
568
569         delete_btn = utils_add_button(popup, MESSAGE_DELETE,
570                         PART_POPUP_BUTTON_1);
571         if (!delete_btn) {
572                 _ERR("failed to add delete btn");
573                 evas_object_del(popup);
574                 return;
575         }
576         inputmgr_add_callback(delete_btn, 0, &delete_user_handler, priv);
577
578         cancel_btn = utils_add_button(popup, MESSAGE_CANCEL,
579                         PART_POPUP_BUTTON_2);
580         if (!cancel_btn) {
581                 _ERR("failed to add cancel btn");
582                 evas_object_del(popup);
583                 return;
584         }
585         inputmgr_add_callback(cancel_btn, 0, &cancel_user_handler, priv);
586         elm_object_focus_set(cancel_btn, EINA_TRUE);
587 }
588
589 static void _del_key_down(int id, void *data, Evas *e, Evas_Object *obj,
590                 Evas_Event_Key_Down *ev)
591 {
592         if (!strcmp(ev->keyname, KEY_ENTER) ||
593                         !strcmp(ev->keyname, KEY_ENTER_REMOTE)) {
594                 _add_delete_popup(data);
595         }
596 }
597
598 static input_handler del_handler = {
599         .focused = _focused,
600         .unfocused = _unfocused,
601         .key_down = _del_key_down
602 };
603
604 static void _load_del_btn(struct _priv *priv)
605 {
606         Evas_Object *btn;
607
608         btn = utils_add_layout(priv->ly, GRP_USER_EDIT_DELETE, true,
609                         PART_USER_EDIT_CONTENTS_DELETE);
610         if (!btn) {
611                 _ERR("failed toa add delete button");
612                 return;
613         }
614         inputmgr_add_callback(btn, 0, &del_handler, priv);
615
616         priv->del = btn;
617 }
618
619 static void _show(void *data)
620 {
621         struct _priv *priv;
622
623         if (!data) {
624                 _ERR("Invalid argument");
625                 return;
626         }
627
628         priv = data;
629
630         evas_object_show(priv->base);
631         elm_object_part_text_set(priv->base, PART_USER_EDIT_TITLE,
632                         MESSAGE_ADD_USER);
633         _load_user_icon(priv, IMAGE_USER_CURRENT_DEFAULT,
634                         IMAGE_USER_CURRENT_DEFAULT_FOCUS);
635         _load_del_btn(priv);
636 }
637
638 static void _hide(void *data)
639 {
640         struct _priv *priv;
641
642         if (!data) {
643                 _ERR("Invalid argument");
644                 return;
645         }
646
647         priv = data;
648         if (priv->del) {
649                 inputmgr_remove_callback(priv->del, &del_handler);
650                 evas_object_del(priv->del);
651                 priv->del = NULL;
652         }
653
654         evas_object_hide(priv->base);
655 }
656
657 static void _destroy(void *data)
658 {
659         struct _priv *priv;
660
661         if (!data) {
662                 _ERR("Invalid argument");
663                 return;
664         }
665
666         priv = data;
667
668         inputmgr_remove_callback(priv->photo, &photo_handler);
669         inputmgr_remove_callback(priv->photo, &lock_handler);
670         inputmgr_remove_callback(priv->done, &done_handler);
671         inputmgr_remove_callback(priv->cancel, &cancel_handler);
672         viewmgr_remove_view(VIEW_PHOTO);
673         evas_object_del(priv->base);
674         free(priv);
675 }
676
677 static view_class vclass = {
678         .view_id = VIEW_USER_EDIT,
679         .create = _create,
680         .show = _show,
681         .hide = _hide,
682         .destroy = _destroy
683 };
684
685 view_class *view_user_edit_get_vclass(void)
686 {
687         return &vclass;
688 }
689