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 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         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_layout){
112                                 evas_object_del(item->content_layout);
113                                 item->content_layout = 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_layout);
131 }
132
133 static Dialogue_Item* _create_item(Evas_Object *obj, Evas_Object *subobj, const char *style)
134 {
135         Widget_Data *wd = elm_widget_data_get(obj);
136         Dialogue_Item *item;
137
138         if (!wd) return NULL;
139         
140         item = ELM_NEW(Dialogue_Item);
141         item->parent = obj;
142         item->content_layout = subobj; 
143         
144         item->bg_layout = elm_layout_add(wd->parent);
145         elm_layout_theme_set(item->bg_layout, "dialoguegroup", "bg", style );
146         elm_object_style_set(item->bg_layout, style);
147         evas_object_size_hint_weight_set(item->bg_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
148         evas_object_size_hint_align_set(item->bg_layout, EVAS_HINT_FILL, 0.0);
149         evas_object_show(item->bg_layout);      
150
151         elm_layout_content_set(item->bg_layout, "swallow", item->content_layout);
152
153         return item;
154 }
155
156 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
157 {
158         _sizing_eval(data);
159 }
160
161 /**
162  * Add a new dialoguegroup to the parent.
163  *
164  * @param parent The parent object
165  * @return The new object or NULL if it cannot be created
166  *
167  * @ingroup DialogueGroup
168  */
169 EAPI Evas_Object *elm_dialoguegroup_add(Evas_Object *parent)
170 {
171         Evas_Object *obj = NULL;
172         Widget_Data *wd = NULL;
173
174         wd = ELM_NEW(Widget_Data);
175         wd->e = evas_object_evas_get(parent);
176         if (wd->e == NULL) return NULL;
177         obj = elm_widget_add(wd->e);
178         ELM_SET_WIDTYPE(widtype, "dialoguegroup");
179         elm_widget_type_set(obj, "dialoguegroup");
180         elm_widget_sub_object_add(parent, obj);
181         elm_widget_data_set(obj, wd);
182         elm_widget_del_hook_set(obj, _del_hook);
183         elm_widget_theme_hook_set(obj, _theme_hook);
184
185         wd->parent = parent;
186         wd->num = 0;
187         
188         wd->box = elm_box_add(parent);
189         evas_object_event_callback_add(wd->box, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
190         evas_object_show(wd->box);
191         elm_widget_resize_object_set(obj, wd->box);
192         
193         _sizing_eval(obj);
194         return obj;
195 }
196
197 /**
198  * Append an item to the dialogue group.
199  *
200  * @param obj dialoguegroup object 
201  * @param subobj item
202  *
203  * @ingroup DialogueGroup
204  */
205 EAPI void
206 elm_dialoguegroup_append(Evas_Object *obj, Evas_Object *subobj)
207 {
208         ELM_CHECK_WIDTYPE(obj, widtype);
209         Widget_Data *wd = elm_widget_data_get(obj);
210         Dialogue_Item *item;
211         
212         if (!wd || !subobj) return;
213         
214         if (!wd->items) {
215                 item = _create_item(obj, subobj, "default");    
216                 elm_box_pack_end(wd->box, item->bg_layout);
217                 wd->items = eina_list_append(wd->items, item);  
218         }
219
220         else {
221                 if (wd->num == 1) {     
222                         item = eina_list_data_get(wd->items);
223                         _change_item_bg(item, "top");           
224                 }               
225                 else {
226                         item = eina_list_data_get( eina_list_last(wd->items) );
227                         _change_item_bg(item, "middle");                
228                 }
229                 item = _create_item(obj, subobj, "bottom");
230                 elm_box_pack_end(wd->box, item->bg_layout);
231                 wd->items = eina_list_append(wd->items, item);          
232         }
233
234         wd->num++;
235         _sizing_eval(obj);
236 }
237
238
239 /**
240  * Prepend an item to the dialogue group.
241  *
242  * @param obj dialoguegroup object 
243  * @param subobj item
244  *
245  * @ingroup DialogueGroup
246  */
247 EAPI void
248 elm_dialoguegroup_prepend(Evas_Object *obj, Evas_Object *subobj)
249 {
250         ELM_CHECK_WIDTYPE(obj, widtype);
251         Widget_Data *wd = elm_widget_data_get(obj);
252         Dialogue_Item *item;
253         
254         if (!wd || !subobj) return;
255         
256         if (!wd->items) {
257                 item = _create_item(obj, subobj, "default");    
258                 if(wd->title_layout)
259                         elm_box_pack_after(wd->box, item->bg_layout, wd->title_layout); 
260                 else                    
261                         elm_box_pack_start(wd->box, item->bg_layout);           
262                 wd->items = eina_list_prepend(wd->items, item); 
263         }
264
265         else {
266                 if (wd->num == 1) {     
267                         item = eina_list_data_get(wd->items);
268                         _change_item_bg(item, "bottom");
269                 }               
270                 else {
271                         item = eina_list_data_get(wd->items);
272                         _change_item_bg(item, "middle");                
273                 }
274                 item = _create_item(obj, subobj, "top");
275                 if(wd->title_layout)
276                         elm_box_pack_after(wd->box, item->bg_layout, wd->title_layout); 
277                 else                    
278                         elm_box_pack_start(wd->box, item->bg_layout);           
279                 wd->items = eina_list_prepend(wd->items, item);         
280         }
281
282         wd->num++;
283         _sizing_eval(obj);
284 }
285
286 /**
287  * Insert an item to the dialogue group just after the specified item.
288  *
289  * @param obj dialoguegroup object 
290  * @param subobj item
291  * @param after specified item existing in the dialogue group
292  *
293  * @ingroup DialogueGroup
294  */
295 EAPI void
296 elm_dialoguegroup_insert_after(Evas_Object *obj, Evas_Object *subobj, Evas_Object *after)
297 {
298         ELM_CHECK_WIDTYPE(obj, widtype);
299         Widget_Data *wd = elm_widget_data_get(obj);
300         Dialogue_Item *after_item, *item;
301         Eina_List *l;
302         const char *style;
303
304         if (!wd || !subobj || !after || !wd->items) return ;
305
306         EINA_LIST_FOREACH(wd->items, l, after_item) {
307                 if( after == after_item->content_layout ) {
308                         style = elm_object_style_get(after_item->bg_layout);
309                         
310                         if( !strcmp(style, "default") ) {
311                                 _change_item_bg(after_item, "top");
312                                 item = _create_item(obj, subobj, "bottom");
313                         }                       
314                         else if( !strcmp(style, "top") || !strcmp(style, "middle") )    
315                                 item = _create_item(obj, subobj, "middle");             
316                         else if( !strcmp(style, "bottom") ) {
317                                 _change_item_bg(after_item, "middle");
318                                 item = _create_item(obj, subobj, "bottom");             
319                         }
320
321                         elm_box_pack_after(wd->box, item->bg_layout, after_item->bg_layout);
322                         wd->items = eina_list_append_relative(wd->items, item, after_item);
323                 }               
324         }
325                 
326         wd->num++;
327
328         _sizing_eval(obj);
329 }
330
331 /**
332  * Insert an item to the dialogue group just before the specified item.
333  *
334  * @param obj dialoguegroup object 
335  * @param subobj item
336  * @param before specified item existing in the dialogue group
337  *
338  * @ingroup DialogueGroup
339  */
340 EAPI void
341 elm_dialoguegroup_insert_before(Evas_Object *obj, Evas_Object *subobj, Evas_Object *before)
342 {
343         ELM_CHECK_WIDTYPE(obj, widtype);
344         Widget_Data *wd = elm_widget_data_get(obj);
345         Dialogue_Item *before_item, *item;
346         Eina_List *l;
347         const char *style;
348         
349         if (!wd || !subobj || !before || !wd->items) return ;
350
351         EINA_LIST_FOREACH(wd->items, l, before_item) {
352                 if( before == before_item->content_layout ) {
353                         style = elm_object_style_get(before_item->bg_layout);
354                         
355                         if( !strcmp(style, "default") ) {
356                                 _change_item_bg(before_item, "bottom");
357                                 item = _create_item(obj, subobj, "top");
358                         }
359                                 
360                         else if( !strcmp(style, "top") ) {
361                                 _change_item_bg(before_item, "middle");
362                                 item = _create_item(obj, subobj, "top");                        
363                         }
364
365                         else if( !strcmp(style, "middle") || !strcmp(style, "bottom") )         
366                                 item = _create_item(obj, subobj, "middle");
367
368                         elm_box_pack_before(wd->box, item->bg_layout, before_item->bg_layout);
369                         wd->items = eina_list_prepend_relative(wd->items, item, before_item);
370                 }               
371         }
372                 
373         wd->num++;
374
375         _sizing_eval(obj);      
376 }
377
378 /**
379  * Remove an item from the dialogue group.
380  *
381  * @param obj dialoguegroup object 
382  * @param subobj item
383  *
384  * @ingroup DialogueGroup
385  */
386 EAPI void
387 elm_dialoguegroup_remove(Evas_Object *obj, Evas_Object *subobj)
388 {
389         ELM_CHECK_WIDTYPE(obj, widtype);
390         Widget_Data *wd = elm_widget_data_get(obj);
391         Dialogue_Item *item;
392         Eina_List *l;
393         
394         if (!wd || !subobj || !wd->items) return ;
395         
396         EINA_LIST_FOREACH(wd->items, l, item) {
397                 if (subobj == item->content_layout) {
398                         if (item->content_layout){
399                                 evas_object_del(item->content_layout);
400                                 item->content_layout = NULL;
401                         }
402                         if (item->bg_layout){
403                                 evas_object_del(item->bg_layout);
404                                 item->bg_layout = NULL;
405                         }
406                         elm_box_unpack(wd->box, item->bg_layout);                       
407                         wd->items = eina_list_remove(wd->items, item);
408                 }
409         }
410                 
411         wd->num--;
412         
413         if (wd->num == 0) return;
414         
415         if (wd->num == 1) {
416                 item = eina_list_data_get(wd->items);
417                 _change_item_bg(item, "default");
418         }
419
420         else {          
421                 item = eina_list_data_get(wd->items);
422                 _change_item_bg(item, "top");
423                 item = eina_list_data_get( eina_list_last(wd->items) );
424                 _change_item_bg(item, "bottom");                
425         }
426
427         _sizing_eval(obj);      
428 }
429
430 /**
431  * Remove all items from the dialogue group.
432  *
433  * @param obj dialoguegroup object 
434  *
435  * @ingroup DialogueGroup
436  */
437 EAPI void
438 elm_dialoguegroup_remove_all(Evas_Object *obj)
439 {
440         ELM_CHECK_WIDTYPE(obj, widtype);
441         _remove_all(obj);       
442         _sizing_eval(obj);      
443 }
444
445
446 /**
447  * Set the title text of the  dialogue group.
448  *
449  * @param obj dialoguegroup object 
450  * @param title title text, if NULL title space will be disappeared 
451  * 
452  * @ingroup DialogueGroup
453  */
454 EAPI void 
455 elm_dialoguegroup_title_set(Evas_Object *obj, const char *title)
456 {
457         ELM_CHECK_WIDTYPE(obj, widtype);
458         Widget_Data *wd = elm_widget_data_get(obj);
459         
460         if (!wd) return ;
461         eina_stringshare_replace(&wd->title, title);
462         if (!title) {
463                 wd->title = NULL;       
464                 elm_box_unpack(wd->box, wd->title_layout);              
465         }
466         if (!wd->title_layout) {
467                 wd->title_layout = elm_layout_add(wd->parent);
468                 elm_widget_sub_object_add(obj, wd->title_layout);
469                 elm_layout_theme_set(wd->title_layout, "dialoguegroup", "base", "title");
470                 evas_object_size_hint_weight_set(wd->title_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
471                 evas_object_size_hint_align_set(wd->title_layout, EVAS_HINT_FILL, 0.0);
472                 evas_object_show(wd->title_layout);     
473         }
474         edje_object_part_text_set(elm_layout_edje_get(wd->title_layout), "text", title);
475         elm_box_pack_start(wd->box, wd->title_layout);
476 }
477
478 /**
479  * Get the title text of the dialogue group
480  *
481  * @param obj The dialoguegroup object
482  * @return The text title string in UTF-8
483  *
484  * @ingroup Slider
485  */
486 EAPI const char *
487 elm_dialoguegroup_title_get(Evas_Object *obj)
488 {
489    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
490    Widget_Data *wd = elm_widget_data_get(obj);
491    if (!wd) return NULL;
492    return wd->title;
493 }
494