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