[dialoguegroup] modify API (add style parameter)
[framework/uifw/elementary.git] / src / lib / elm_dialoguegroup.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include <Ecore.h>
4
5 /**
6  * @defgroup DialogueGroup DialogueGroup 
7  * @ingroup Elementary
8  *
9  * Using dialoguegroup, you can make a dialogue group.
10  */
11
12 struct _Dialogue_Item
13 {
14         Evas_Object *parent;
15         Evas_Object *bg_layout;
16         Evas_Object *content;
17         Elm_Dialoguegroup_Item_Style style;
18         const char *location;
19         Eina_Bool press;
20 };
21
22
23 typedef struct _Widget_Data Widget_Data;
24 struct _Widget_Data
25 {
26         Evas_Object *parent;
27         Evas *e;
28         Evas_Object *box;
29         Evas_Object *title_layout;
30         const char *title;
31         unsigned int num;
32         Eina_List *items;
33 };
34
35 static const char*widtype = NULL;
36
37 static void _del_hook(Evas_Object *obj);
38 static void _theme_hook(Evas_Object *obj);
39 static void _sizing_eval(Evas_Object *obj);
40 static void _disable_hook(Evas_Object *obj);
41
42 static void _remove_all(Evas_Object *obj);
43 static void _change_item_bg(Dialogue_Item *item, const char *location);
44 static Dialogue_Item* _create_item(Evas_Object *obj, Evas_Object *subobj, Elm_Dialoguegroup_Item_Style style, const char *location);
45
46         
47 static void
48 _del_hook(Evas_Object *obj)
49 {
50         Widget_Data *wd = elm_widget_data_get(obj);
51
52         if (!wd) return;
53         if (wd->title) eina_stringshare_del(wd->title);
54         
55         _remove_all(obj);
56         
57         if (wd->box){
58                 evas_object_del(wd->box);
59                 wd->box = NULL;
60         }
61         
62         free(wd);
63 }
64
65
66 static void
67 _theme_hook(Evas_Object *obj)
68 {
69         Widget_Data *wd = elm_widget_data_get(obj);
70         Eina_List *l;
71         Dialogue_Item *item;    
72         
73         if (!wd) return;        
74         if (wd->title) {
75                 elm_layout_theme_set(wd->title_layout, "dialoguegroup", "base", "title");
76                 edje_object_part_text_set(elm_layout_edje_get(wd->title_layout), "text", wd->title);
77         }
78         EINA_LIST_FOREACH(wd->items, l, item) 
79                 _change_item_bg( item, item->location );        
80         _sizing_eval(obj);
81 }
82
83 static void
84 _disable_hook(Evas_Object *obj)
85 {
86
87 }
88
89 static void
90 _sizing_eval(Evas_Object *obj)
91 {
92         Widget_Data *wd = elm_widget_data_get(obj);
93         Evas_Coord minw, minh, maxw, maxh;
94         
95         if (!wd) return;
96         evas_object_size_hint_min_get(wd->box, &minw, &minh);
97         evas_object_size_hint_max_get(wd->box, &maxw, &maxh);
98         evas_object_size_hint_min_set(obj, minw, minh);
99         evas_object_size_hint_max_set(obj, maxw, maxh);
100 }
101
102 static void _remove_all(Evas_Object *obj)
103 {
104         Widget_Data *wd = elm_widget_data_get(obj);
105         Dialogue_Item *item;    
106
107         if (!wd) return;
108
109         wd->num = 0;
110         
111         if (wd->items) {
112                 EINA_LIST_FREE(wd->items, item) {
113                         if (item->content){
114                                 evas_object_del(item->content);
115                                 item->content = NULL;
116                         }
117                         if (item->bg_layout){
118                                 evas_object_del(item->bg_layout);
119                                 item->bg_layout = NULL;
120                         }
121                         if (item->location)
122                                 eina_stringshare_del(item->location);
123                         free(item);
124                 }
125         }
126 }
127 static void _set_item_theme(Dialogue_Item *item, const char *location)
128 {
129         if (!item) return;
130
131         if (item->style == ELM_DIALOGUEGROUP_ITEM_STYLE_DEFAULT)
132                 elm_layout_theme_set(item->bg_layout, "dialoguegroup", "bg", location);
133         else if (item->style == ELM_DIALOGUEGROUP_ITEM_STYLE_EDITFIELD)
134                 elm_layout_theme_set(item->bg_layout, "dialoguegroup", "editfield", location);
135 }
136
137 static void _change_item_bg(Dialogue_Item *item, const char *location)
138 {
139         if (!item) return;
140         
141         eina_stringshare_replace(&item->location, location);
142         _set_item_theme(item, location);
143         elm_layout_content_set(item->bg_layout, "swallow", item->content);
144         if(item->press == EINA_TRUE)
145                 edje_object_signal_emit(elm_layout_edje_get(item->bg_layout), "elm,state,press,on", "elm");
146         else
147                 edje_object_signal_emit(elm_layout_edje_get(item->bg_layout), "elm,state,press,off", "elm");    
148 }
149
150 static Dialogue_Item* _create_item(Evas_Object *obj, Evas_Object *subobj, Elm_Dialoguegroup_Item_Style style, const char *location)
151 {
152         Widget_Data *wd = elm_widget_data_get(obj);
153         Dialogue_Item *item;
154
155         if (!wd) return NULL;
156         
157         item = ELM_NEW(Dialogue_Item);
158         item->parent = obj;
159         item->content = subobj;
160         item->press = EINA_TRUE;
161         item->style = style;
162         eina_stringshare_replace(&item->location, location);
163         
164         item->bg_layout = elm_layout_add(wd->parent);
165         _set_item_theme(item, location);
166         evas_object_size_hint_weight_set(item->bg_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
167         evas_object_size_hint_align_set(item->bg_layout, EVAS_HINT_FILL, 0.0);
168         evas_object_show(item->bg_layout);      
169
170         elm_layout_content_set(item->bg_layout, "swallow", item->content);
171
172         return item;
173 }
174
175 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
176 {
177         _sizing_eval(data);
178 }
179
180 /**
181  * Add a new dialoguegroup to the parent.
182  *
183  * @param parent The parent object
184  * @return The new object or NULL if it cannot be created
185  *
186  * @ingroup DialogueGroup
187  */
188 EAPI Evas_Object *elm_dialoguegroup_add(Evas_Object *parent)
189 {
190         Evas_Object *obj = NULL;
191         Widget_Data *wd = NULL;
192
193         wd = ELM_NEW(Widget_Data);
194         wd->e = evas_object_evas_get(parent);
195         if (wd->e == NULL) return NULL;
196         obj = elm_widget_add(wd->e);
197         ELM_SET_WIDTYPE(widtype, "dialoguegroup");
198         elm_widget_type_set(obj, "dialoguegroup");
199         elm_widget_sub_object_add(parent, obj);
200         elm_widget_data_set(obj, wd);
201         elm_widget_del_hook_set(obj, _del_hook);
202         elm_widget_theme_hook_set(obj, _theme_hook);
203
204         wd->parent = parent;
205         wd->num = 0;
206         
207         wd->box = elm_box_add(parent);
208         evas_object_event_callback_add(wd->box, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
209         evas_object_show(wd->box);
210         elm_widget_resize_object_set(obj, wd->box);
211         
212         _sizing_eval(obj);
213         return obj;
214 }
215
216 /**
217  * Append an item to the dialogue group.
218  *
219  * @param obj dialoguegroup object 
220  * @param subobj item
221  * @return Dialogue_Item pointer, just made by this function
222  * 
223  * @ingroup DialogueGroup
224  */
225 EAPI Dialogue_Item *
226 elm_dialoguegroup_append(Evas_Object *obj, Evas_Object *subobj, Elm_Dialoguegroup_Item_Style style)
227 {
228         ELM_CHECK_WIDTYPE(obj, widtype) NULL;
229         Widget_Data *wd = elm_widget_data_get(obj);
230         Dialogue_Item *item;
231         
232         if (!wd || !subobj) return NULL;
233         
234         if (!wd->items) {
235                 item = _create_item(obj, subobj, style, "default");     
236                 elm_box_pack_end(wd->box, item->bg_layout);
237                 wd->items = eina_list_append(wd->items, item);  
238         }
239
240         else {
241                 if (wd->num == 1) {     
242                         item = eina_list_data_get(wd->items);
243                         _change_item_bg(item, "top");           
244                 }               
245                 else {
246                         item = eina_list_data_get( eina_list_last(wd->items) );
247                         _change_item_bg(item, "middle");                
248                 }
249                 item = _create_item(obj, subobj, style, "bottom");
250                 elm_box_pack_end(wd->box, item->bg_layout);
251                 wd->items = eina_list_append(wd->items, item);          
252         }
253
254         wd->num++;
255         _sizing_eval(obj);
256         return item;
257 }
258
259
260 /**
261  * Prepend an item to the dialogue group.
262  *
263  * @param obj dialoguegroup object 
264  * @param subobj item
265  * @return Dialogue_Item pointer, just made by this function
266  *
267  * @ingroup DialogueGroup
268  */
269 EAPI Dialogue_Item *
270 elm_dialoguegroup_prepend(Evas_Object *obj, Evas_Object *subobj, Elm_Dialoguegroup_Item_Style style)
271 {
272         ELM_CHECK_WIDTYPE(obj, widtype) NULL;
273         Widget_Data *wd = elm_widget_data_get(obj);
274         Dialogue_Item *item;
275         
276         if (!wd || !subobj) return NULL;
277         
278         if (!wd->items) {
279                 item = _create_item(obj, subobj, style, "default");     
280                 if(wd->title_layout)
281                         elm_box_pack_after(wd->box, item->bg_layout, wd->title_layout); 
282                 else                    
283                         elm_box_pack_start(wd->box, item->bg_layout);           
284                 wd->items = eina_list_prepend(wd->items, item); 
285         }
286
287         else {
288                 if (wd->num == 1) {     
289                         item = eina_list_data_get(wd->items);
290                         _change_item_bg(item, "bottom");
291                 }               
292                 else {
293                         item = eina_list_data_get(wd->items);
294                         _change_item_bg(item, "middle");                
295                 }
296                 item = _create_item(obj, subobj, style, "top");
297                 if(wd->title_layout)
298                         elm_box_pack_after(wd->box, item->bg_layout, wd->title_layout); 
299                 else                    
300                         elm_box_pack_start(wd->box, item->bg_layout);           
301                 wd->items = eina_list_prepend(wd->items, item);         
302         }
303
304         wd->num++;
305         _sizing_eval(obj);
306         return item;
307 }
308
309 /**
310  * Insert an item to the dialogue group just after the specified item.
311  *
312  * @param obj dialoguegroup object 
313  * @param subobj item
314  * @param after specified item existing in the dialogue group
315  * @return Dialogue_Item pointer, just made by this function
316  *
317  * @ingroup DialogueGroup
318  */
319 EAPI Dialogue_Item * 
320 elm_dialoguegroup_insert_after(Evas_Object *obj, Evas_Object *subobj, Dialogue_Item *after, Elm_Dialoguegroup_Item_Style style)
321 {
322         ELM_CHECK_WIDTYPE(obj, widtype) NULL;
323         Widget_Data *wd = elm_widget_data_get(obj);
324         Dialogue_Item *after_item, *item;
325         Eina_List *l;
326
327         if (!wd || !subobj || !after || !wd->items) return NULL;
328
329         EINA_LIST_FOREACH(wd->items, l, after_item) {
330                 if(after == after_item) {
331                         if( !strcmp(item->location, "default") ) {
332                                 _change_item_bg(after_item, "top");
333                                 item = _create_item(obj, subobj, style, "bottom");
334                         }                       
335                         else if( !strcmp(item->location, "top") || !strcmp(item->location, "middle") )  
336                                 item = _create_item(obj, subobj, style, "middle");              
337                         else if( !strcmp(item->location, "bottom") ) {
338                                 _change_item_bg(after_item, "middle");
339                                 item = _create_item(obj, subobj, style, "bottom");              
340                         }
341
342                         elm_box_pack_after(wd->box, item->bg_layout, after_item->bg_layout);
343                         wd->items = eina_list_append_relative(wd->items, item, after_item);
344                 }               
345         }
346                 
347         wd->num++;
348         _sizing_eval(obj);
349         return item;
350 }
351
352 /**
353  * Insert an item to the dialogue group just before the specified item.
354  *
355  * @param obj dialoguegroup object 
356  * @param subobj item
357  * @param before specified item existing in the dialogue group
358  * @return Dialogue_Item pointer, just made by this function
359  *
360  * @ingroup DialogueGroup
361  */
362 EAPI Dialogue_Item *
363 elm_dialoguegroup_insert_before(Evas_Object *obj, Evas_Object *subobj, Dialogue_Item *before, Elm_Dialoguegroup_Item_Style style)
364 {
365         ELM_CHECK_WIDTYPE(obj, widtype) NULL;
366         Widget_Data *wd = elm_widget_data_get(obj);
367         Dialogue_Item *before_item, *item;
368         Eina_List *l;
369         
370         if (!wd || !subobj || !before || !wd->items) return NULL;
371
372         EINA_LIST_FOREACH(wd->items, l, before_item) {
373                 if(before == before_item) {
374                         if( !strcmp(item->location, "default") ) {
375                                 _change_item_bg(before_item, "bottom");
376                                 item = _create_item(obj, subobj, style, "top");
377                         }
378                                 
379                         else if( !strcmp(item->location, "top") ) {
380                                 _change_item_bg(before_item, "middle");
381                                 item = _create_item(obj, subobj, style, "top");                 
382                         }
383
384                         else if( !strcmp(item->location, "middle") || !strcmp(item->location, "bottom") )
385                                 item = _create_item(obj, subobj, style, "middle");
386
387                         elm_box_pack_before(wd->box, item->bg_layout, before_item->bg_layout);
388                         wd->items = eina_list_prepend_relative(wd->items, item, before_item);
389                 }               
390         }
391                 
392         wd->num++;
393         _sizing_eval(obj);      
394         return item;
395 }
396
397 /**
398  * Remove an item from the dialogue group.
399  *
400  * @param obj dialoguegroup object 
401  * @param subobj item
402  *
403  * @ingroup DialogueGroup
404  */
405 EAPI void
406 elm_dialoguegroup_remove(Dialogue_Item *item)
407 {
408         ELM_CHECK_WIDTYPE(item->parent, widtype) ;
409         Dialogue_Item *current_item;
410         Widget_Data *wd = elm_widget_data_get(item->parent);
411         Eina_List *l;
412         
413         if (!wd || !wd->items || !item) return ;
414         
415         EINA_LIST_FOREACH(wd->items, l, current_item) {
416                 if (current_item == item) {
417                         if (current_item->content){
418                                 evas_object_del(current_item->content);
419                                 current_item->content = NULL;
420                         }
421                         if (current_item->bg_layout){
422                                 evas_object_del(current_item->bg_layout);
423                                 current_item->bg_layout = NULL;
424                         }
425                         elm_box_unpack(wd->box, current_item->bg_layout);                       
426                         wd->items = eina_list_remove(wd->items, current_item);
427                 }
428         }
429                 
430         wd->num--;
431         
432         if (wd->num == 0) return;
433         
434         if (wd->num == 1) {
435                 current_item = eina_list_data_get(wd->items);
436                 _change_item_bg(current_item, "default");
437         }
438
439         else {          
440                 current_item = eina_list_data_get(wd->items);
441                 _change_item_bg(current_item, "top");
442                 current_item = eina_list_data_get( eina_list_last(wd->items) );
443                 _change_item_bg(current_item, "bottom");                
444         }
445
446         _sizing_eval(item->parent);     
447 }
448
449 /**
450  * Remove all items from the dialogue group.
451  *
452  * @param obj dialoguegroup object 
453  *
454  * @ingroup DialogueGroup
455  */
456 EAPI void
457 elm_dialoguegroup_remove_all(Evas_Object *obj)
458 {
459         ELM_CHECK_WIDTYPE(obj, widtype);
460         _remove_all(obj);       
461         _sizing_eval(obj);      
462 }
463
464
465 /**
466  * Set the title text of the  dialogue group.
467  *
468  * @param obj dialoguegroup object 
469  * @param title title text, if NULL title space will be disappeared 
470  * 
471  * @ingroup DialogueGroup
472  */
473 EAPI void 
474 elm_dialoguegroup_title_set(Evas_Object *obj, const char *title)
475 {
476         ELM_CHECK_WIDTYPE(obj, widtype);
477         Widget_Data *wd = elm_widget_data_get(obj);
478         
479         if (!wd) return ;
480         eina_stringshare_replace(&wd->title, title);
481         if (!title) {
482                 wd->title = NULL;       
483                 elm_box_unpack(wd->box, wd->title_layout);              
484         }
485         if (!wd->title_layout) {
486                 wd->title_layout = elm_layout_add(wd->parent);
487                 elm_widget_sub_object_add(obj, wd->title_layout);
488                 elm_layout_theme_set(wd->title_layout, "dialoguegroup", "base", "title");
489                 evas_object_size_hint_weight_set(wd->title_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
490                 evas_object_size_hint_align_set(wd->title_layout, EVAS_HINT_FILL, 0.0);
491                 evas_object_show(wd->title_layout);     
492         }
493         edje_object_part_text_set(elm_layout_edje_get(wd->title_layout), "text", title);
494         elm_box_pack_start(wd->box, wd->title_layout);
495 }
496
497 /**
498  * Get the title text of the dialogue group
499  *
500  * @param obj The dialoguegroup object
501  * @return The text title string in UTF-8
502  *
503  * @ingroup DialogueGroup
504  */
505 EAPI const char *
506 elm_dialoguegroup_title_get(Evas_Object *obj)
507 {
508    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
509    Widget_Data *wd = elm_widget_data_get(obj);
510    if (!wd) return NULL;
511    return wd->title;
512 }
513
514 /**
515  * Set whether the press effect will be shown or not
516  *
517  * @param obj The dialoguegroup object
518  * @param item Dialogue_Item pointer
519  * @param press If set as 1, press effect will be shown 
520  *
521  * @ingroup DialogueGroup 
522  */
523 EAPI void 
524 elm_dialoguegroup_press_effect_set(Dialogue_Item *item, Eina_Bool press)
525 {
526    ELM_CHECK_WIDTYPE(item->parent, widtype) ;
527    if(!item) return;
528    
529    item->press = press;
530    if(press == EINA_TRUE)
531            edje_object_signal_emit(elm_layout_edje_get(item->bg_layout), "elm,state,press,on", "elm");
532    else
533            edje_object_signal_emit(elm_layout_edje_get(item->bg_layout), "elm,state,press,off", "elm"); 
534 }
535
536 /**
537  * Get the press effect state
538  *
539  * @param obj The dialoguegroup object
540  * @param item Dialogue_Item pointer
541  * @return 1 if press effect on, 0 if press effect off 
542  *
543  * @ingroup DialogueGroup 
544  */
545 EAPI Eina_Bool
546 elm_dialoguegroup_press_effect_get(Dialogue_Item *item)
547 {
548    ELM_CHECK_WIDTYPE(item->parent, widtype) EINA_FALSE;
549    if(!item) return EINA_FALSE;
550    
551    return item->press;
552 }
553
554 /**
555  * Get the conetent object from the specified dialogue item
556  *
557  * @param obj The dialoguegroup object
558  * @param item Dialogue_Item pointer
559  * @return content object 
560  *
561  * @ingroup DialogueGroup 
562  */
563 EAPI Evas_Object *
564 elm_dialoguegroup_item_content_get(Dialogue_Item *item)
565 {
566    ELM_CHECK_WIDTYPE(item->parent, widtype) EINA_FALSE;
567    if(!item) return EINA_FALSE;
568    
569    return item->content;
570 }