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