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