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