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