Remove needless functions
[profile/mobile/apps/native/accessibility-setting.git] / src / setting-common-draw-genlist.cpp
1 /*
2  * setting
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
5  *
6  * Contact: MyoungJune Park <mj2004.park@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include "setting-common-draw-widget.h"
23 #include "setting-debug.h"
24
25 #include <app.h>
26
27 #define DEF_BUF_SIZE 32
28
29 static Evas_Object *_gl_Gendial_content_get(void *data, Evas_Object *obj, const char *part);
30 static char *gendialNewTextGetCb(void *data, Evas_Object *obj, const char *part);
31 static void _gl_Gendial_del(void *data, Evas_Object *obj);
32
33 #define DEFINE_ITC1(style, name) \
34         const Elm_Genlist_Item_Class name = { \
35                 .version = 0, \
36                 .refcount = 0, \
37                 .delete_me = EINA_FALSE, \
38                 .homogeneous = EINA_FALSE, \
39                 .item_style = style, \
40                 .decorate_item_style = NULL, \
41                 .decorate_all_item_style = NULL, \
42                 .func = {gendialNewTextGetCb, _gl_Gendial_content_get, NULL, _gl_Gendial_del, NULL, NULL} \
43         };
44
45 DEFINE_ITC1(SETTING_GENLIST_ICON_1LINE_STYLE, itc_1text);
46 DEFINE_ITC1(SETTING_GENLIST_ICON_1LINE_STYLE, itc_1text_1icon_2);
47 DEFINE_ITC1(SETTING_GENLIST_ICON_1LINE_STYLE, itc_1icon_1text_sub);
48 DEFINE_ITC1(SETTING_GENLIST_ICON_1LINE_STYLE, itc_1text_1icon);
49 DEFINE_ITC1(SETTING_GENLIST_ICON_1LINE_STYLE, itc_1text_1icon_3);
50 DEFINE_ITC1(SETTING_GENLIST_ICON_1LINE_STYLE, itc_1text_2icon);
51 DEFINE_ITC1(SETTING_GENLIST_ICON_1LINE_STYLE, itc_1text_1icon_divider);
52 DEFINE_ITC1(SETTING_GENLIST_ICON_1LINE_STYLE, itc_multiline_1text_1icon);
53 DEFINE_ITC1(SETTING_GENLIST_1ICON_STYLE, itc_bg_1icon);
54 DEFINE_ITC1(SETTING_GENLIST_1ICON_STYLE, itc_1icon);
55
56 DEFINE_ITC1("1text", itc_normal_1text);
57
58 /********************************************************************/
59 DEFINE_ITC1(SETTING_GENLIST_2LINE_STYLE, itc_2text_2);
60 /********************************************************************/
61
62 DEFINE_ITC1(SETTING_GENLIST_2LINE_STYLE, itc_2text);
63 DEFINE_ITC1(SETTING_GENLIST_2LINE_STYLE, itc_2text_1icon_3);
64 DEFINE_ITC1(SETTING_GENLIST_2LINE_STYLE, itc_2text_1icon_2);
65 DEFINE_ITC1(SETTING_GENLIST_2LINE_STYLE, itc_2text_3);
66 DEFINE_ITC1(SETTING_GENLIST_2LINE_STYLE, itc_2text_2icon_3);
67 DEFINE_ITC1(SETTING_GENLIST_2LINE_STYLE, itc_multiline_2text);
68 DEFINE_ITC1(SETTING_GENLIST_2LINE_STYLE, itc_2text_3_parent);
69
70 DEFINE_ITC1(SETTING_GENLIST_MULTILINE_STYLE, itc_multiline_text);
71
72 DEFINE_ITC1(SETTING_GENLIST_GROUP_INDEX_STYLE, itc_group_item);
73
74 static void __radio_changed(void *data, Evas_Object *obj, void *event_info)
75 {
76         retm_if(data == NULL, "Data parameter is NULL");
77         GenGroupItemData *list_item =
78                         (GenGroupItemData *)data;
79         list_item->chk_status = elm_radio_value_get(obj); /* for update */
80 }
81
82 static void __chk_changed(void *data, Evas_Object *obj, void *event_info)
83 {
84         retm_if(data == NULL, "Data parameter is NULL");
85         GenGroupItemData *list_item =
86                         (GenGroupItemData *)data;
87         list_item->chk_status = elm_check_state_get(obj); /* for update */
88 }
89
90 static void _gl_Gendial_sel(void *data, Evas_Object *obj, void *event_info)
91 {
92
93
94         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
95         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
96         elm_genlist_item_selected_set(item, EINA_FALSE);
97 }
98
99 static char *gendialNewTextGetCb(void *data, Evas_Object *obj, const char *part)
100 {
101         GenGroupItemData *item_data = static_cast<GenGroupItemData*>(data);
102         std::string ret;
103         std::string part_str = part ? part : std::string{};
104
105         /*------------------------------------------------------------- */
106         /* style == multiline ---------> "elm.text.multiline" */
107         /*------------------------------------------------------------- */
108         /* style != multiline ---------> "elm.text" */
109         /*                                               "elm.text.sub" */
110         /*------------------------------------------------------------- */
111         if (item_data->itc == "multiline" && part_str == "elm.text.multiline") {
112                         ret = item_data->keyStr.str();
113         } else {
114                 if (part_str == "elm.text" || part_str == "elm.text.main" || part_str == "elm.text.main.left"
115                         || part_str == "elm.text.main.left.top" || part_str == "elm.text.multiline") {
116                         ret = item_data->keyStr.str();
117                 } else if (part_str == "elm.text.sub" || part_str == "elm.text.2" || part_str == "elm.text.sub.left.bottom") {
118                         ret = item_data->sub_desc.str();
119                 }
120         }
121         return ret.empty() ? nullptr : strdup(ret.c_str());
122 }
123
124 static Evas_Object *__add_check(GenGroupItemData *item_data,
125                 Evas_Object *parent)
126 {
127         retv_if(!item_data || !parent, NULL);
128
129         Evas_Object *check = elm_check_add(parent);
130
131         elm_check_state_set(check, item_data->chk_status);
132         evas_object_propagate_events_set(check, 0);
133         evas_object_size_hint_align_set(check, EVAS_HINT_FILL, EVAS_HINT_FILL);
134         evas_object_size_hint_weight_set(check, EVAS_HINT_EXPAND,
135                         EVAS_HINT_EXPAND);
136
137         if (SwallowType::CHECK == item_data->swallow_type) {
138                 elm_check_state_pointer_set(check,
139                                 (Eina_Bool *)(&(item_data->chk_status)));
140                 evas_object_pass_events_set(check, 1);
141         } else {
142                 evas_object_pass_events_set(check, 1);
143         }
144
145         item_data->eo_check = check;
146
147         if (item_data->chk_change_cb) {
148                 evas_object_smart_callback_add(check, "changed",
149                                 item_data->chk_change_cb, item_data);
150         } else {
151                 evas_object_smart_callback_add(check, "changed", __chk_changed,
152                                 item_data);
153         }
154         evas_object_show(check);
155
156         return check;
157 }
158
159 static Evas_Object *__add_toggle(GenGroupItemData *item_data,
160                 Evas_Object *parent)
161 {
162         retv_if(!item_data || !parent, NULL);
163         Evas_Object *check = elm_check_add(parent);
164
165         elm_check_state_set(check, item_data->chk_status);
166         evas_object_propagate_events_set(check, 0);
167         evas_object_size_hint_align_set(check, EVAS_HINT_FILL, EVAS_HINT_FILL);
168         evas_object_size_hint_weight_set(check, EVAS_HINT_EXPAND,
169                         EVAS_HINT_EXPAND);
170
171         if (SwallowType::CHECK == item_data->swallow_type) {
172                 elm_check_state_pointer_set(check,
173                                 (Eina_Bool *)(&(item_data->chk_status)));
174                 evas_object_pass_events_set(check, 1);
175         } else {
176                 evas_object_pass_events_set(check, 1);
177         }
178
179         item_data->eo_check = check;
180
181         if (item_data->chk_change_cb) {
182                 evas_object_smart_callback_add(check, "changed",
183                                 item_data->chk_change_cb, item_data);
184         } else {
185                 evas_object_smart_callback_add(check, "changed", __chk_changed,
186                                 item_data);
187         }
188         evas_object_show(check);
189
190         elm_object_style_set(check, "on&off");
191         elm_atspi_accessible_relationship_append(check,
192                         ELM_ATSPI_RELATION_CONTROLLED_BY, item_data->item);
193         elm_atspi_accessible_relationship_append(item_data->item,
194                         ELM_ATSPI_RELATION_DESCRIBED_BY, check);
195         elm_atspi_accessible_relationship_append(item_data->item,
196                         ELM_ATSPI_RELATION_CONTROLLER_FOR, check);
197         return check;
198 }
199
200 static Evas_Object *__add_radio_text(GenGroupItemData *item_data,
201                 Evas_Object *parent)
202 {
203         retv_if(!item_data || !parent, NULL);
204         if (!item_data->rgd) { /* exceptional handling */
205                 item_data->rgd = elm_radio_add(parent);
206                 elm_radio_state_value_set(item_data->rgd, -1);
207         }
208         Evas_Object *radio = elm_radio_add(parent);
209         evas_object_propagate_events_set(radio, EINA_FALSE);
210         evas_object_repeat_events_set(radio, EINA_FALSE);
211         elm_radio_state_value_set(radio, item_data->chk_status);
212         elm_radio_group_add(radio, item_data->rgd);
213         evas_object_show(radio);
214         item_data->eo_check = radio;
215         if (item_data->chk_change_cb) {
216                 evas_object_smart_callback_add(radio, "changed",
217                                 item_data->chk_change_cb, item_data);
218         } else {
219                 evas_object_smart_callback_add(radio, "changed",
220                                 __radio_changed, item_data);
221         }
222         return radio;
223 }
224
225 static Evas_Object *__add_left_default(GenGroupItemData *item_data,
226                 Evas_Object *parent)
227 {
228         retv_if(!item_data || !parent, NULL);
229
230         if (item_data->l_swallow_path.empty())
231                 return NULL;
232
233         if (SwallowType::ICON_IMAGE == item_data->swallow_type) {
234                 Evas_Object *icon = elm_icon_add(parent);
235                 setting_decorate_image_RGBA(icon, 15, 41, 73, 255);
236                 elm_image_file_set(icon, item_data->l_swallow_path.c_str(), NULL);
237                 evas_object_size_hint_aspect_set(icon,
238                                 EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
239                 return icon;
240         } else {
241                 Evas_Object * c = elm_image_add(parent);
242
243                 elm_image_file_set(c, item_data->l_swallow_path.c_str(), NULL);
244                 setting_decorate_image_RGBA(c, 14, 41, 73, 255);
245                 evas_object_size_hint_align_set(c, EVAS_HINT_FILL,
246                                 EVAS_HINT_FILL);
247                 evas_object_size_hint_weight_set(c, EVAS_HINT_EXPAND,
248                                 EVAS_HINT_EXPAND);
249                 return c;
250         }
251
252 }
253
254 static Evas_Object *__add_right_default(GenGroupItemData *item_data,
255                 Evas_Object *parent)
256 {
257         retv_if(!item_data || !parent, NULL);
258
259         if (item_data->r_swallow_path.empty())
260                 return NULL;
261
262         Evas_Object *icon = elm_image_add(parent);
263
264         elm_image_file_set(icon, item_data->r_swallow_path.c_str(), NULL);
265         evas_object_size_hint_align_set(icon, 0.0, EVAS_HINT_FILL);
266         evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND,
267                         EVAS_HINT_EXPAND);
268
269         return icon;
270 }
271
272 /* draw handler */
273 using drawer_fp = Evas_Object*(*)(GenGroupItemData *item_data, Evas_Object *parent);
274
275 struct ContentDrawer
276 {
277         SwallowType type; /* ui type */
278         drawer_fp draw;
279 };
280
281 static ContentDrawer cd_left[static_cast<int>(SwallowType::MAX)] = {
282                 /*base objects */
283                 { SwallowType::CHECK, __add_check },
284
285                 /*other compelx objects */
286                 /* setting-network */
287                 { SwallowType::RADIO_1TEXT, __add_radio_text },
288 };
289
290 static ContentDrawer cd_right[static_cast<int>(SwallowType::MAX)] = {
291                 /*right part object of the type */
292                 { SwallowType::ICON_RADIO, __add_toggle },
293 };
294
295
296 /* When X marked button clicked, make string as empty. */
297 static void __multiline_eraser_clicked(void *data, Evas_Object *obj,
298                 void *event_info)
299 {
300         GenGroupItemData *list_item = (GenGroupItemData *)data;
301         Evas_Object *entry = (Evas_Object *)elm_object_item_part_content_get(list_item->item,
302                         "elm.icon.entry");
303         /* After button is clicked, entry should get focus again. */
304         elm_object_focus_set(entry, EINA_TRUE);
305         elm_entry_entry_set(entry, "");
306 }
307
308 static Evas_Object *_gl_Gendial_content_get(void *data, Evas_Object *obj, const char *part)
309 {
310         GenGroupItemData *item_data = (GenGroupItemData *)data;
311         ContentDrawer *cd_list = NULL;
312         drawer_fp fp = NULL;
313         retv_if(!item_data, NULL);
314
315         if (!safeStrCmp(part, "elm.swallow.icon")) { /* LEFT AREA */
316                 fp = __add_left_default;
317                 cd_list = cd_left;
318
319         } else if (!safeStrCmp(part, "elm.swallow.end")) { /* RIGHT AREA */
320                 fp = __add_right_default; /*hold default drawer */
321                 cd_list = cd_right;
322
323         } else if (!safeStrCmp(part, "elm.icon.1")) { /* LEFT AREA */
324                 fp = __add_left_default; /*hold default drawer */
325                 cd_list = cd_left;
326
327         } else if (!safeStrCmp(part, "elm.icon.2")) { /* RIGHT AREA */
328                 fp = __add_right_default; /*hold default drawer */
329                 cd_list = cd_right;
330
331         } else if (!safeStrCmp(part, "elm.icon")) { /* CENTER WHOLE */
332                 fp = __add_left_default; /*hold default drawer */
333                 cd_list = cd_left;
334
335         } else if (!safeStrCmp(part, "elm.icon.eraser")) {
336                 /*fp = __add_button_eraser; */
337                 Evas_Object *btn = elm_button_add(obj);
338                 /*Make "X" marked button by changing style. */
339                 elm_object_style_set(btn, "editfield_clear");
340                 evas_object_smart_callback_add(btn, "clicked", __multiline_eraser_clicked, item_data);
341                 return btn;
342
343         } else if (!safeStrCmp(part, "elm.icon.edit")) {
344                 Evas_Object *btn = elm_button_add(obj);
345                 elm_object_style_set(btn, "minus");
346                 evas_object_propagate_events_set(btn, EINA_FALSE);
347                 return btn;
348         }
349         /* End. */
350
351         if (cd_list) {
352                 int idx = 0;
353                 for (; idx < static_cast<int>(SwallowType::MAX); idx++) {
354                         /*match using swallow type */
355                         if (item_data->swallow_type == cd_list[idx].type) {
356                                 fp = cd_list[idx].draw;
357                                 break;
358                         }
359                 }
360         }
361         return fp ? fp(item_data, obj) : NULL;
362 }
363
364 static void _gl_Gendial_del(void *data, Evas_Object *obj)
365 {
366         GenGroupItemData *item_data = (GenGroupItemData *)data;
367         if (item_data) {
368                 item_data->eo_check = NULL;/*set to NULL at once */
369                 item_data->itc = {};
370
371                 if (item_data->notify) {
372                         evas_object_del(item_data->notify);
373                         item_data->notify = NULL;
374                 }
375
376                 __BACK_POINTER_UNSET(item_data);
377                 delete item_data;
378         }
379 }
380
381 /**
382  * Create separator style item with title
383  *
384  * @return a pointer to GenGroupItemData
385  */
386 GenGroupItemData *createGendialTitleItem(
387                 Evas_Object *genlist, const Elm_Genlist_Item_Class *itc,
388                 const std::string& keyStr)
389 {
390         auto item_data = new GenGroupItemData;
391         setting_retvm_if(!item_data, NULL, "new failed");
392         item_data->keyStr = keyStr;
393         if (itc && itc->item_style)
394                 item_data->itc = itc->item_style;
395
396         item_data->item = elm_genlist_item_append(genlist, itc, item_data, NULL, ELM_GENLIST_ITEM_NONE, _gl_Gendial_sel, NULL);
397
398         elm_genlist_item_select_mode_set(item_data->item, ELM_OBJECT_SELECT_MODE_NONE);
399
400         return item_data;
401 }
402
403 /**
404  * Create common style item with menu icon
405  *
406  * @return a pointer to GenGroupItemData
407  */
408 GenGroupItemData *createGendialGroupItem(
409                 Evas_Object *genlist, const Elm_Genlist_Item_Class *itc,
410                 SettingCallback gl_sel,
411                 void *sel_data, SwallowType swallow_type, int chk_status, const std::string& keyStr,
412                 const std::string& sub_desc, SettingCallback chk_change_cb)
413 {
414         auto item_data = new GenGroupItemData;
415         setting_retvm_if(!item_data, NULL, "new failed");
416
417         item_data->keyStr = keyStr;
418
419         item_data->sub_desc = sub_desc;
420
421         item_data->swallow_type = swallow_type;
422         item_data->chk_status = chk_status;
423         item_data->chk_change_cb = chk_change_cb;
424         if (itc && itc->item_style)
425                 item_data->itc = itc->item_style;
426
427         const char *insert_type = (const char *)evas_object_data_get(genlist, "InsertType");
428
429         if (!gl_sel)
430                 gl_sel = _gl_Gendial_sel;
431
432         if (0 == safeStrCmp(insert_type, "Insert before")) {
433                 item_data->item = elm_genlist_item_insert_before(genlist, itc, item_data, NULL, NULL, ELM_GENLIST_ITEM_NONE, gl_sel, sel_data);
434         } else if (0 == safeStrCmp(insert_type, "Insert after")) {
435                 item_data->item = elm_genlist_item_insert_after(genlist, itc, item_data, NULL, NULL, ELM_GENLIST_ITEM_NONE, gl_sel, sel_data);
436         } else if (0 == safeStrCmp(insert_type, "Prepend")) {
437                 item_data->item = elm_genlist_item_prepend(genlist, itc, item_data, NULL, ELM_GENLIST_ITEM_NONE, gl_sel, sel_data);
438         } else {
439                 item_data->item = elm_genlist_item_append(genlist, itc, item_data, NULL, ELM_GENLIST_ITEM_NONE, gl_sel, sel_data);
440         }
441         /*redundant process,it should be due to invokers,but maybe they
442          * forget it */
443         evas_object_data_set(genlist, "InsertType", NULL);
444
445         return item_data;
446 }
447
448 void __gl_realized_cb(void *data, Evas_Object *obj, void *event_info)
449 {
450         setting_retm_if(event_info == NULL,
451                         "invalid parameter: event_info is NULL");
452         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
453
454         elm_object_item_data_get(item);
455 }
456
457 /*for check,radio,slider etc.. */
458 void setting_update_gl_item_chk_status(GenGroupItemData *item_data,
459                 int status)
460 {
461         if (item_data && item_data->chk_status != status) {
462                 item_data->chk_status = status;
463                 if (item_data->item) {
464                         elm_genlist_item_fields_update(item_data->item, "*",
465                                         ELM_GENLIST_ITEM_FIELD_CONTENT);
466                 }
467         }
468 }