elm_selectioninfo added
[framework/uifw/elementary.git] / src / lib / elm_selectioninfo.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4 #include <Elementary.h>
5 #include "elm_priv.h"
6
7
8 /**
9  * @defgroup Selectioninfo selectioninfo
10  * @ingroup Elementary
11  *
12  * Provide for notifying user about the number of currently selected items
13  * especially when user is on the selection mode for specific action
14  * such as Move, Delete, or Share, etc.
15  *
16  */
17
18 #define _EDJ(x) (Evas_Object *)elm_layout_edje_get(x)
19
20 typedef struct _Widget_Data Widget_Data;
21
22 struct _Widget_Data
23 {
24         Evas_Object* selectioninfo;
25         Evas_Object* content;
26         Evas_Object* parent;
27         Eina_Bool* check_state;
28         int check_count;
29         char label_text[128];
30 };
31
32 static const char *widtype = NULL;
33 static void _del_hook(Evas_Object *obj);
34 static void _theme_hook(Evas_Object *obj);
35 static void _sizing_eval(Evas_Object *obj);
36 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
37 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
38 static void _calc(Evas_Object *obj);
39 static void _content_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
40 static void _show(void *data, Evas *e, Evas_Object *obj, void *event_info);
41 static void _hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
42 static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
43
44 static void
45 _del_pre_hook(Evas_Object *obj)
46 {
47         evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
48         evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE, _resize, obj);
49         evas_object_event_callback_del_full(obj, EVAS_CALLBACK_SHOW, _show, obj);
50         evas_object_event_callback_del_full(obj, EVAS_CALLBACK_HIDE, _hide, obj);
51 }
52
53 static void
54 _del_hook(Evas_Object *obj)
55 {
56         Widget_Data *wd = elm_widget_data_get(obj);
57         if (!wd) return;
58         elm_selectioninfo_content_set(obj, NULL);
59         elm_selectioninfo_parent_set(obj, NULL);
60         free(wd);
61 }
62
63 static void
64 _theme_hook(Evas_Object *obj)
65 {
66         Widget_Data *wd = elm_widget_data_get(obj);
67         if (!wd) return;
68         _elm_theme_object_set(obj, wd->selectioninfo, "selectioninfo", "base", "default");
69         edje_object_scale_set(wd->selectioninfo, elm_widget_scale_get(obj) *_elm_config->scale);
70         _sizing_eval(obj);
71 }
72
73 static void
74 _sizing_eval(Evas_Object *obj)
75 {
76         Widget_Data *wd = elm_widget_data_get(obj);
77         Evas_Coord x,y,w,h;
78         if (!wd) return;
79         if (!wd->parent) return;
80         evas_object_geometry_get(wd->parent, &x, &y, &w, &h);
81         evas_object_move(obj, x, y);
82         evas_object_resize(obj, w, h);
83 }
84
85 static void
86 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
87 {
88         _sizing_eval(data);
89 }
90
91 static void
92 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
93 {
94         Widget_Data *wd = elm_widget_data_get(obj);
95         if (!wd) return;
96         if (event_info == wd->content) wd->content = NULL;
97 }
98
99 static void
100 _resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
101 {
102         _calc(obj);
103 }
104
105 static void
106 _content_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
107 {
108         _calc(data);
109 }
110
111 static void
112 _calc(Evas_Object *obj)
113 {
114         Widget_Data *wd = elm_widget_data_get(obj);
115         Evas_Coord minw = -1, minh = -1;
116         Evas_Coord x, y, w, h;
117         if (!wd) return;
118         evas_object_geometry_get(obj, &x, &y, &w, &h);
119         edje_object_size_min_calc(wd->selectioninfo, &minw, &minh);
120
121         if (wd->content)
122         {
123                 evas_object_move(wd->selectioninfo, x, y + h - minh);
124                 evas_object_resize(wd->selectioninfo, w, minh);
125         }
126    
127         _sizing_eval(obj);
128 }
129
130 static void
131 _show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
132 {
133         Widget_Data *wd = elm_widget_data_get(obj);
134         if (!wd) return;
135         evas_object_show(wd->selectioninfo);
136 }
137
138 static void
139 _hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
140 {
141         Widget_Data *wd = elm_widget_data_get(obj);
142         if (!wd) return;
143         evas_object_hide(wd->selectioninfo);
144 }
145
146 static void
147 _parent_del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
148 {
149         Widget_Data *wd = elm_widget_data_get(obj);
150         if (!wd) return;
151         wd->parent = NULL;
152         evas_object_hide(obj);
153 }
154
155 static void
156 _parent_hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
157 {
158         Widget_Data *wd = elm_widget_data_get(obj);
159         if (!wd) return;
160         wd->parent = NULL;
161         evas_object_hide(obj);
162 }
163
164 /**
165  * Add a new selectioninfo to the parent
166  *
167  * @param parent The parent object
168  * @return The new object or NULL if it cannot be created
169  *
170  * @ingroup Selectioninfo
171  */
172 EAPI Evas_Object *
173 elm_selectioninfo_add(Evas_Object *parent)
174 {
175         Evas_Object *obj;
176         Evas *e;
177         Widget_Data *wd;
178
179         wd = ELM_NEW(Widget_Data);
180         e = evas_object_evas_get(parent);
181         obj = elm_widget_add(e);
182         ELM_SET_WIDTYPE(widtype, "selectioninfo");
183         elm_widget_type_set(obj, "selectioninfo");
184         elm_widget_sub_object_add(parent, obj);
185         elm_widget_data_set(obj, wd);
186         elm_widget_del_pre_hook_set(obj, _del_pre_hook);
187         elm_widget_del_hook_set(obj, _del_hook);
188         elm_widget_theme_hook_set(obj, _theme_hook);
189
190         wd->selectioninfo = edje_object_add(e);
191         _elm_theme_object_set(obj, wd->selectioninfo, "selectioninfo", "base", "default");
192         _resize(obj, NULL, obj, NULL);
193         
194         elm_selectioninfo_parent_set(obj, parent);
195
196         evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
197         evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
198         evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _resize, obj);
199         evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, obj);
200         evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, obj);
201
202         _sizing_eval(obj);
203         return obj;
204 }
205
206 /**
207  * Set the selectioninfo content
208  *
209  * @param obj The selctioninfo object
210  * @param content The content will be filled in this selectioninfo object
211  *
212  * @ingroup Notify
213  */
214 EAPI void
215 elm_selectioninfo_content_set(Evas_Object *obj, Evas_Object *content)
216 {
217         ELM_CHECK_WIDTYPE(obj, widtype);
218         Widget_Data *wd = elm_widget_data_get(obj);
219         if (!wd) return;
220         if (wd->content)
221         {
222                 evas_object_event_callback_del_full(wd->content, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
223                 evas_object_event_callback_del_full(wd->content, EVAS_CALLBACK_RESIZE, _content_resize, obj);
224                 evas_object_del(wd->content);
225                 wd->content = NULL;
226         }
227    
228         if (content)
229         {
230                 elm_widget_sub_object_add(obj, content);
231                 wd->content = content;
232                 evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
233                 evas_object_event_callback_add(content, EVAS_CALLBACK_RESIZE, _content_resize, obj);
234                 edje_object_part_swallow(wd->selectioninfo, "elm.swallow.content", content);
235         
236                 _sizing_eval(obj);
237         }
238         
239         _calc(obj);
240 }
241
242 /**
243  * Set the selectioninfo parent
244  *
245  * @param obj The selectioninfo object
246  * @param parent The new parent
247  *
248  * @ingroup Selectioninfo
249  */
250 EAPI void
251 elm_selectioninfo_parent_set(Evas_Object *obj, Evas_Object *parent)
252 {
253         ELM_CHECK_WIDTYPE(obj, widtype);
254         Widget_Data *wd = elm_widget_data_get(obj);
255         if (!wd) return;
256         if (wd->parent)
257         {
258                 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
259                 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE, _changed_size_hints, obj);
260                 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE, _changed_size_hints, obj);
261                 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_DEL, _parent_del, obj);
262                 evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_HIDE, _parent_hide, obj);
263                 wd->parent = NULL;
264         }
265    
266         if (parent)
267         {
268                 wd->parent = parent;
269                 evas_object_event_callback_add(parent, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
270                 evas_object_event_callback_add(parent, EVAS_CALLBACK_RESIZE, _changed_size_hints, obj);
271                 evas_object_event_callback_add(parent, EVAS_CALLBACK_MOVE, _changed_size_hints, obj);
272                 evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL, _parent_del, obj);
273                 evas_object_event_callback_add(parent, EVAS_CALLBACK_HIDE, _parent_hide, obj);
274                 _sizing_eval(obj);
275         }
276         
277         _calc(obj);
278 }
279
280 /**
281  * Set the check state to the selectioninfo
282  *
283  * @param obj The selectioninfo object
284  * @param state The check state
285  * @param count The check count
286  *
287  * @ingroup Selectioninfo
288  */
289 EAPI void
290 elm_selectioninfo_check_state_set(Evas_Object *obj, Eina_Bool *state, int count)
291 {
292         ELM_CHECK_WIDTYPE(obj, widtype);
293         Widget_Data *wd = elm_widget_data_get(obj);
294         if (!wd) return;
295         wd->check_state = state;
296         wd->check_count = count;
297 }
298
299 /**
300  * Show the selectioninfo
301  *
302  * @param obj The selectioninfo object
303  *
304  * @ingroup Selectioninfo
305  */
306 EAPI void
307 elm_selectioninfo_show(Evas_Object *obj)
308 {
309         ELM_CHECK_WIDTYPE(obj, widtype);
310         Widget_Data *wd = elm_widget_data_get(obj);
311         if (!wd) return;
312
313         int i;
314         int state_count = 0;
315         for (i=0; i<wd->check_count; i++)
316         {
317                 if (wd->check_state[i])
318                         state_count++;
319         }
320
321         if (state_count == 0)
322         {
323                 evas_object_hide(wd->selectioninfo);
324         }
325         else
326         {
327                 if (state_count == 1)
328                         sprintf(wd->label_text, "%d File Selected", state_count);
329                 else
330                         sprintf(wd->label_text, "%d Files Selected", state_count);
331                 edje_object_part_text_set(_EDJ(wd->content), "elm.text", strdup(wd->label_text));
332                 evas_object_show(wd->selectioninfo);    
333         }          
334 }
335