Merge branch 'master' of youmin.ha@165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL-pkgs...
[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  * @addtogroup DialogueGroup DialogueGroup 
7  *
8  * Using dialoguegroup, you can make a dialogue group.
9  */
10
11 typedef struct _Dialogue_Item Dialogue_Item;
12 struct _Dialogue_Item
13 {
14         Evas_Object *parent;
15         Evas_Object *bg_layout;
16         Evas_Object *content_layout;
17 };
18
19
20 typedef struct _Widget_Data Widget_Data;
21 struct _Widget_Data
22 {
23         Evas_Object *parent;
24         Evas *e;
25         Evas_Object *box;
26         unsigned int num;
27
28         Eina_List *items;
29 };
30
31 static void _del_hook(Evas_Object *obj);
32 static void _theme_hook(Evas_Object *obj);
33 static void _sizing_eval(Evas_Object *obj);
34 static void _disable_hook(Evas_Object *obj);
35
36 static void _remove_all(Evas_Object *obj);
37 static void _change_item_bg(Dialogue_Item *item, const char *style);
38 static Dialogue_Item* _create_item(Evas_Object *obj, Evas_Object *subobj, const char *style);
39
40         
41 static void
42 _del_hook(Evas_Object *obj)
43 {
44         Widget_Data *wd = elm_widget_data_get(obj);
45         Dialogue_Item *item;    
46
47         if (!wd) return;
48
49         _remove_all(obj);
50         
51         if (wd->box){
52                 evas_object_del(wd->box);
53                 wd->box = NULL;
54         }
55         
56         free(wd);
57 }
58
59
60 static void
61 _theme_hook(Evas_Object *obj)
62 {
63         Widget_Data *wd = elm_widget_data_get(obj);
64         Eina_List *l;
65         Dialogue_Item *item;    
66         
67         if (!wd)
68                 return; 
69         EINA_LIST_FOREACH(wd->items, l, item) 
70                 _change_item_bg( item, elm_widget_style_get(item->bg_layout) ); 
71
72         _sizing_eval(obj);
73 }
74
75 static void
76 _disable_hook(Evas_Object *obj)
77 {
78
79 }
80
81 static void
82 _sizing_eval(Evas_Object *obj)
83 {
84         Widget_Data *wd = elm_widget_data_get(obj);
85         Eina_List *l;
86         Dialogue_Item *item;
87         Evas_Coord minw, minh, maxw, maxh;
88         
89         if (!wd) return;
90         evas_object_size_hint_min_get(wd->box, &minw, &minh);
91         evas_object_size_hint_max_get(wd->box, &maxw, &maxh);
92         evas_object_size_hint_min_set(obj, minw, minh);
93         evas_object_size_hint_max_set(obj, maxw, maxh);
94 }
95
96 static void _remove_all(Evas_Object *obj)
97 {
98         Widget_Data *wd = elm_widget_data_get(obj);
99         Dialogue_Item *item;    
100
101         if (!wd) return;
102
103         wd->num = 0;
104         
105         if (wd->items) {
106                 EINA_LIST_FREE(wd->items, item) {
107                         if (item->content_layout){
108                                 evas_object_del(item->content_layout);
109                                 item->content_layout = NULL;
110                         }
111                         if (item->bg_layout){
112                                 evas_object_del(item->bg_layout);
113                                 item->bg_layout = NULL;
114                         }
115                         free(item);
116                 }
117         }
118 }
119
120 static void _change_item_bg(Dialogue_Item *item, const char *style)
121 {
122         if ( ! item ) return;
123         
124         elm_layout_theme_set(item->bg_layout, "dialoguegroup", "bg", style);
125         elm_object_style_set(item->bg_layout, style);
126         elm_layout_content_set(item->bg_layout, "swallow", item->content_layout);
127 }
128
129 static Dialogue_Item* _create_item(Evas_Object *obj, Evas_Object *subobj, const char *style)
130 {
131         Widget_Data *wd = elm_widget_data_get(obj);
132         Dialogue_Item *item;
133
134         if ( ! wd ) return NULL;
135         
136         item = ELM_NEW(Dialogue_Item);
137         item->parent = obj;
138         item->content_layout = subobj; 
139         
140         item->bg_layout = elm_layout_add(wd->parent);
141         elm_layout_theme_set(item->bg_layout, "dialoguegroup", "bg", style );
142         elm_object_style_set(item->bg_layout, style);
143         evas_object_size_hint_weight_set(item->bg_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
144         evas_object_size_hint_align_set(item->bg_layout, EVAS_HINT_FILL, 0.0);
145         evas_object_show(item->bg_layout);      
146
147         elm_layout_content_set(item->bg_layout, "swallow", item->content_layout);
148
149         return item;
150 }
151
152 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
153 {
154         _sizing_eval(data);
155 }
156
157 /**
158  * Add a new dialoguegroup to the parent.
159  *
160  * @param parent The parent object
161  * @return The new object or NULL if it cannot be created
162  *
163  * @ingroup DialogueGroup
164  */
165 EAPI Evas_Object *elm_dialoguegroup_add(Evas_Object *parent)
166 {
167         Evas_Object *obj = NULL;
168         Widget_Data *wd = NULL;
169
170         wd = ELM_NEW(Widget_Data);
171         wd->e = evas_object_evas_get(parent);
172         if (wd->e == NULL) return NULL;
173         obj = elm_widget_add(wd->e);
174         elm_widget_type_set(obj, "dialoguegroup");
175         elm_widget_sub_object_add(parent, obj);
176         elm_widget_data_set(obj, wd);
177         elm_widget_del_hook_set(obj, _del_hook);
178         elm_widget_theme_hook_set(obj, _theme_hook);
179
180         wd->parent = parent;
181         wd->num = 0;
182         
183         wd->box = elm_box_add(parent);
184         evas_object_event_callback_add(wd->box, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
185         evas_object_show(wd->box);
186         elm_widget_resize_object_set(obj, wd->box);
187         
188         _sizing_eval(obj);
189         return obj;
190 }
191
192 /**
193  * Append an item to the dialogue group.
194  *
195  * @param obj dialoguegroup object 
196  * @param subobj item
197  *
198  * @ingroup DialogueGroup
199  */
200 EAPI void
201 elm_dialoguegroup_append(Evas_Object *obj, Evas_Object *subobj)
202 {
203         Widget_Data *wd = elm_widget_data_get(obj);
204         Dialogue_Item *item;
205         
206         if ( ! wd || ! subobj ) return;
207         
208         if ( !wd->items ) {
209                 item = _create_item(obj, subobj, "default");    
210                 elm_box_pack_end(wd->box, item->bg_layout);
211                 wd->items = eina_list_append(wd->items, item);  
212         }
213
214         else {
215                 if ( wd->num == 1 ) {   
216                         item = eina_list_data_get(wd->items);
217                         _change_item_bg(item, "top");           
218                 }               
219                 else {
220                         item = eina_list_data_get( eina_list_last(wd->items) );
221                         _change_item_bg(item, "middle");                
222                 }
223                 item = _create_item(obj, subobj, "bottom");
224                 elm_box_pack_end(wd->box, item->bg_layout);
225                 wd->items = eina_list_append(wd->items, item);          
226         }
227
228         wd->num++;
229         _sizing_eval(obj);
230 }
231
232
233 /**
234  * Prepend an item to the dialogue group.
235  *
236  * @param obj dialoguegroup object 
237  * @param subobj item
238  *
239  * @ingroup DialogueGroup
240  */
241 EAPI void
242 elm_dialoguegroup_prepend(Evas_Object *obj, Evas_Object *subobj)
243 {
244         Widget_Data *wd = elm_widget_data_get(obj);
245         Dialogue_Item *item;
246         
247         if ( ! wd || ! subobj ) return;
248         
249         if ( !wd->items ) {
250                 item = _create_item(obj, subobj, "default");    
251                 elm_box_pack_start(wd->box, item->bg_layout);
252                 wd->items = eina_list_prepend(wd->items, item); 
253         }
254
255         else {
256                 if ( wd->num == 1 ) {   
257                         item = eina_list_data_get(wd->items);
258                         _change_item_bg(item, "bottom");
259                 }               
260                 else {
261                         item = eina_list_data_get( wd->items );
262                         _change_item_bg(item, "middle");                
263                 }
264                 item = _create_item(obj, subobj, "top");
265                 elm_box_pack_start(wd->box, item->bg_layout);
266                 wd->items = eina_list_prepend(wd->items, item);         
267         }
268
269         wd->num++;
270         _sizing_eval(obj);
271 }
272
273 /**
274  * Insert an item to the dialogue group just after the specified item.
275  *
276  * @param obj dialoguegroup object 
277  * @param subobj item
278  * @param after specified item existing in the dialogue group
279  *
280  * @ingroup DialogueGroup
281  */
282 EAPI void
283 elm_dialoguegroup_insert_after(Evas_Object *obj, Evas_Object *subobj, Evas_Object *after)
284 {
285         Widget_Data *wd = elm_widget_data_get(obj);
286         Dialogue_Item *after_item, *item;
287         Eina_List *l;
288         const char *style;
289
290         if ( !wd || !subobj || !after || !wd->items)
291                 return ;
292         
293         EINA_LIST_FOREACH(wd->items, l, after_item) {
294                 if( after == after_item->content_layout ) {
295                         style = elm_object_style_get(after_item->bg_layout);
296                         
297                         if( !strcmp(style, "default") ) {
298                                 _change_item_bg(after_item, "top");
299                                 item = _create_item(obj, subobj, "bottom");
300                         }
301                         
302                         else if( !strcmp(style, "top") || !strcmp(style, "middle") )            
303                                 item = _create_item(obj, subobj, "middle");
304                         
305                         else if( !strcmp(style, "bottom") ) {
306                                 _change_item_bg(after_item, "middle");
307                                 item = _create_item(obj, subobj, "bottom");                     
308                         }
309
310                         elm_box_pack_after(wd->box, item->bg_layout, after_item->bg_layout);
311                         wd->items = eina_list_append_relative(wd->items, item, after_item);
312                 }               
313         }
314                 
315         wd->num++;
316
317         _sizing_eval(obj);
318 }
319
320 /**
321  * Insert an item to the dialogue group just before the specified item.
322  *
323  * @param obj dialoguegroup object 
324  * @param subobj item
325  * @param before specified item existing in the dialogue group
326  *
327  * @ingroup DialogueGroup
328  */
329 EAPI void
330 elm_dialoguegroup_insert_before(Evas_Object *obj, Evas_Object *subobj, Evas_Object *before)
331 {
332         Widget_Data *wd = elm_widget_data_get(obj);
333         Dialogue_Item *before_item, *item;
334         Eina_List *l;
335         const char *style;
336         
337         if ( !wd || !subobj || !before || !wd->items)
338                 return ;
339
340         EINA_LIST_FOREACH(wd->items, l, before_item) {
341                 if( before == before_item->content_layout ) {
342                         style = elm_object_style_get(before_item->bg_layout);
343                         
344                         if( !strcmp(style, "default") ) {
345                                 _change_item_bg(before_item, "bottom");
346                                 item = _create_item(obj, subobj, "top");
347                         }
348                                 
349                         else if( !strcmp(style, "top") ) {
350                                 _change_item_bg(before_item, "middle");
351                                 item = _create_item(obj, subobj, "top");                        
352                         }
353
354                         else if( !strcmp(style, "middle") || !strcmp(style, "bottom") )         
355                                 item = _create_item(obj, subobj, "middle");
356
357                         elm_box_pack_before(wd->box, item->bg_layout, before_item->bg_layout);
358                         wd->items = eina_list_prepend_relative(wd->items, item, before_item);
359                 }               
360         }
361                 
362         wd->num++;
363
364         _sizing_eval(obj);      
365 }
366
367 /**
368  * Remove an item from the dialogue group.
369  *
370  * @param obj dialoguegroup object 
371  * @param subobj item
372  *
373  * @ingroup DialogueGroup
374  */
375 EAPI void
376 elm_dialoguegroup_remove(Evas_Object *obj, Evas_Object *subobj)
377 {
378         Widget_Data *wd = elm_widget_data_get(obj);
379         Dialogue_Item *item;
380         Eina_List *l;
381         
382         if ( !wd || !subobj || !wd->items)
383                 return ;
384         
385         EINA_LIST_FOREACH(wd->items, l, item) {
386                 if (subobj == item->content_layout) {
387                         if (item->content_layout){
388                                 evas_object_del(item->content_layout);
389                                 item->content_layout = NULL;
390                         }
391                         if (item->bg_layout){
392                                 evas_object_del(item->bg_layout);
393                                 item->bg_layout = NULL;
394                         }
395                         elm_box_unpack(wd->box, item->bg_layout);                       
396                         wd->items = eina_list_remove(wd->items, item);
397                 }
398         }
399                 
400         wd->num--;
401         
402         if ( wd->num == 0 ) 
403                 return;
404         
405         if ( wd->num == 1 ) {
406                 item = eina_list_data_get(wd->items);
407                 _change_item_bg(item, "default");
408         }
409
410         else {          
411                 item = eina_list_data_get(wd->items);
412                 _change_item_bg(item, "top");
413                 item = eina_list_data_get( eina_list_last(wd->items) );
414                 _change_item_bg(item, "bottom");                
415         }
416
417         _sizing_eval(obj);      
418 }
419
420 /**
421  * Remove all items from the dialogue group.
422  *
423  * @param obj dialoguegroup object 
424  *
425  * @ingroup DialogueGroup
426  */
427 EAPI void
428 elm_dialoguegroup_remove_all(Evas_Object *obj)
429 {
430         _remove_all(obj);       
431         _sizing_eval(obj);      
432 }