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