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