1 #include "e.h"
2 
3 typedef struct _E_Widget_Data E_Widget_Data;
4 struct _E_Widget_Data
5 {
6    Evas_Object *o_check;
7    Evas_Object *o_icon;
8    int         *valptr;
9    Eina_List *widgets_enable;
10    Eina_List *widgets_disable;
11 };
12 
13 /* local subsystem functions */
14 
15 static void
_extern_obj_enable_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)16 _extern_obj_enable_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
17 {
18    E_Widget_Data *wd = data;
19    wd->widgets_enable = eina_list_remove(wd->widgets_enable, obj);
20 }
21 
22 static void
_extern_obj_disable_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)23 _extern_obj_disable_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
24 {
25    E_Widget_Data *wd = data;
26    wd->widgets_disable = eina_list_remove(wd->widgets_disable, obj);
27 }
28 
29 static void
_e_wid_del_hook(Evas_Object * obj)30 _e_wid_del_hook(Evas_Object *obj)
31 {
32    E_Widget_Data *wd;
33    Evas_Object *o;
34 
35    wd = e_widget_data_get(obj);
36    EINA_LIST_FREE(wd->widgets_enable, o)
37      evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _extern_obj_enable_del, wd);
38    EINA_LIST_FREE(wd->widgets_disable, o)
39      evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL, _extern_obj_disable_del, wd);
40    free(wd);
41 }
42 
43 static void
_e_wid_focus_hook(Evas_Object * obj)44 _e_wid_focus_hook(Evas_Object *obj)
45 {
46    E_Widget_Data *wd;
47 
48    wd = e_widget_data_get(obj);
49    if (e_widget_focus_get(obj))
50      {
51         edje_object_signal_emit(wd->o_check, "e,state,focused", "e");
52         evas_object_focus_set(wd->o_check, 1);
53      }
54    else
55      {
56         edje_object_signal_emit(wd->o_check, "e,state,unfocused", "e");
57         evas_object_focus_set(wd->o_check, 0);
58      }
59 }
60 
61 static void
_e_wid_do(Evas_Object * obj)62 _e_wid_do(Evas_Object *obj)
63 {
64    E_Widget_Data *wd;
65 
66    if (e_widget_disabled_get(obj)) return;
67 
68    wd = e_widget_data_get(obj);
69    if (wd->valptr)
70      {
71         Eina_List *l;
72         Evas_Object *o;
73 
74         if (*(wd->valptr) == 0)
75           {
76              *(wd->valptr) = 1;
77              edje_object_signal_emit(wd->o_check, "e,state,checked", "e");
78           }
79         else
80           {
81              *(wd->valptr) = 0;
82              edje_object_signal_emit(wd->o_check, "e,state,unchecked", "e");
83           }
84         EINA_LIST_FOREACH(wd->widgets_enable, l, o)
85           e_widget_disabled_set(o, *wd->valptr);
86         EINA_LIST_FOREACH(wd->widgets_disable, l, o)
87           e_widget_disabled_set(o, !(*wd->valptr));
88      }
89    evas_object_smart_callback_call(obj, "changed", NULL);
90    e_widget_change(obj);
91 }
92 
93 static void
_e_wid_activate_hook(Evas_Object * obj)94 _e_wid_activate_hook(Evas_Object *obj)
95 {
96    _e_wid_do(obj);
97 }
98 
99 static void
_e_wid_disable_hook(Evas_Object * obj)100 _e_wid_disable_hook(Evas_Object *obj)
101 {
102    E_Widget_Data *wd;
103 
104    wd = e_widget_data_get(obj);
105    if (e_widget_disabled_get(obj))
106      edje_object_signal_emit(wd->o_check, "e,state,disabled", "e");
107    else
108      edje_object_signal_emit(wd->o_check, "e,state,enabled", "e");
109 }
110 
111 static void
_e_wid_signal_cb1(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)112 _e_wid_signal_cb1(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
113 {
114    _e_wid_do(data);
115 }
116 
117 static void
_e_wid_focus_steal(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)118 _e_wid_focus_steal(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
119 {
120    e_widget_focus_steal(data);
121 }
122 
123 /* externally accessible functions */
124 
125 /**
126  * Creates a check box widget
127  *
128  * @param evas pointer
129  * @param label the text to assign to check widget
130  * @param val pointer to int where changes are stored
131  * @return the newly created evas object
132  */
133 E_API Evas_Object *
e_widget_check_add(Evas * evas,const char * label,int * val)134 e_widget_check_add(Evas *evas, const char *label, int *val)
135 {
136    Evas_Object *obj, *o;
137    E_Widget_Data *wd;
138    Evas_Coord mw, mh;
139 
140    obj = e_widget_add(evas);
141 
142    e_widget_del_hook_set(obj, _e_wid_del_hook);
143    e_widget_focus_hook_set(obj, _e_wid_focus_hook);
144    e_widget_activate_hook_set(obj, _e_wid_activate_hook);
145    e_widget_disable_hook_set(obj, _e_wid_disable_hook);
146    wd = calloc(1, sizeof(E_Widget_Data));
147    wd->valptr = val;
148    e_widget_data_set(obj, wd);
149 
150    o = edje_object_add(evas);
151    wd->o_check = o;
152    e_theme_edje_object_set(o, "base/theme/widgets",
153                            "e/widgets/check");
154    edje_object_signal_callback_add(o, "e,action,toggle", "*", _e_wid_signal_cb1, obj);
155    edje_object_part_text_set(o, "e.text.label", label);
156    evas_object_show(o);
157    edje_object_size_min_calc(o, &mw, &mh);
158    e_widget_size_min_set(obj, mw, mh);
159    if (wd->valptr)
160      {
161         if (*(wd->valptr)) edje_object_signal_emit(o, "e,state,checked", "e");
162      }
163 
164    e_widget_sub_object_add(obj, o);
165    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_wid_focus_steal, obj);
166    e_widget_resize_object_set(obj, o);
167 
168    return obj;
169 }
170 
171 /**
172  * Sets the value of the check box
173  *
174  * @param check the check box widget
175  * @param checked the value to set the widget too
176  */
177 E_API void
e_widget_check_checked_set(Evas_Object * check,int checked)178 e_widget_check_checked_set(Evas_Object *check, int checked)
179 {
180    E_Widget_Data *wd;
181 
182    wd = e_widget_data_get(check);
183    if (wd->valptr)
184      *(wd->valptr) = checked;
185    if (checked)
186      edje_object_signal_emit(wd->o_check, "e,state,checked", "e");
187    else
188      edje_object_signal_emit(wd->o_check, "e,state,unchecked", "e");
189 }
190 
191 /**
192  * Sets the value of the check box
193  *
194  * @param check the check box widget
195  * @param val pointer to int where changes are stored
196  */
197 E_API void
e_widget_check_valptr_set(Evas_Object * check,int * val)198 e_widget_check_valptr_set(Evas_Object *check, int *val)
199 {
200    E_Widget_Data *wd;
201    int state;
202 
203    wd = e_widget_data_get(check);
204    state = wd->valptr ? *wd->valptr : 0;
205    wd->valptr = val;
206    if (state == (wd->valptr && *wd->valptr)) return;
207    if (wd->valptr && *wd->valptr)
208      edje_object_signal_emit(wd->o_check, "e,state,checked", "e");
209    else
210      edje_object_signal_emit(wd->o_check, "e,state,unchecked", "e");
211 }
212 
213 /**
214  * Get the value of the check box
215  *
216  * @param check the check box widget
217  * @return the value of the check box
218  */
219 E_API int
e_widget_check_checked_get(Evas_Object * check)220 e_widget_check_checked_get(Evas_Object *check)
221 {
222    E_Widget_Data *wd;
223    int ret;
224 
225    wd = e_widget_data_get(check);
226    if (wd->valptr)
227      ret = *(wd->valptr);
228    else
229      ret = -1;
230 
231    return ret;
232 }
233 
234 /**
235  * Add widget to disable when check object is checked
236  * @param check the check box widget
237  * @param obj the object to disable when @p check is checked
238  */
239 E_API void
e_widget_check_widget_disable_on_checked_add(Evas_Object * check,Evas_Object * obj)240 e_widget_check_widget_disable_on_checked_add(Evas_Object *check, Evas_Object *obj)
241 {
242    E_Widget_Data *wd;
243 
244    EINA_SAFETY_ON_NULL_RETURN(check);
245    EINA_SAFETY_ON_NULL_RETURN(obj);
246    wd = e_widget_data_get(check);
247    EINA_SAFETY_ON_NULL_RETURN(wd);
248    if (wd->valptr)
249      e_widget_disabled_set(obj, *wd->valptr);
250    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _extern_obj_enable_del, wd);
251    wd->widgets_enable = eina_list_append(wd->widgets_enable, obj);
252 }
253 
254 /**
255  * Add widget to disable when check object is unchecked
256  * @param check the check box widget
257  * @param obj the object to disable when @p check is not unchecked
258  */
259 E_API void
e_widget_check_widget_disable_on_unchecked_add(Evas_Object * check,Evas_Object * obj)260 e_widget_check_widget_disable_on_unchecked_add(Evas_Object *check, Evas_Object *obj)
261 {
262    E_Widget_Data *wd;
263 
264    EINA_SAFETY_ON_NULL_RETURN(check);
265    EINA_SAFETY_ON_NULL_RETURN(obj);
266    wd = e_widget_data_get(check);
267    EINA_SAFETY_ON_NULL_RETURN(wd);
268    if (wd->valptr)
269      e_widget_disabled_set(obj, !(*wd->valptr));
270    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _extern_obj_disable_del, wd);
271    wd->widgets_disable = eina_list_append(wd->widgets_disable, obj);
272 }
273 
274 
275 /**
276  * Creates a check box widget with icon
277  *
278  * @param evas pointer
279  * @param label the text to assign to check widget
280  * @param icon the path to the icon file
281  * @param icon_w the minimum wdith of the icon
282  * @param icon_h the minimum height of the icon
283  * @param val pointer to int where changes are stored
284  * @return the newly created evas object
285  */
286 E_API Evas_Object *
e_widget_check_icon_add(Evas * evas,const char * label,const char * icon,int icon_w,int icon_h,int * val)287 e_widget_check_icon_add(Evas *evas, const char *label, const char *icon, int icon_w, int icon_h, int *val)
288 {
289    Evas_Object *obj, *o, *o2;
290    E_Widget_Data *wd;
291    Evas_Coord mw, mh;
292 
293    obj = e_widget_add(evas);
294 
295    e_widget_del_hook_set(obj, _e_wid_del_hook);
296    e_widget_focus_hook_set(obj, _e_wid_focus_hook);
297    e_widget_activate_hook_set(obj, _e_wid_activate_hook);
298    e_widget_disable_hook_set(obj, _e_wid_disable_hook);
299    wd = calloc(1, sizeof(E_Widget_Data));
300    wd->valptr = val;
301    e_widget_data_set(obj, wd);
302 
303    o = edje_object_add(evas);
304    wd->o_check = o;
305    e_theme_edje_object_set(o, "base/theme/widgets",
306                            "e/widgets/check_icon");
307    edje_object_signal_callback_add(o, "e,action,toggle", "*", _e_wid_signal_cb1, obj);
308    edje_object_part_text_set(o, "e.text.label", label);
309    evas_object_show(o);
310    if (label)
311      {
312         edje_object_signal_emit(o, "e,state,labeled", "e");
313         edje_object_message_signal_process(o);
314      }
315    if (icon)
316      {
317         if (icon[0] == '/')
318           {
319              o2 = e_icon_add(evas);
320              e_icon_file_set(o2, icon);
321           }
322         else
323           {
324              o2 = edje_object_add(evas);
325              e_util_edje_icon_set(o2, icon);
326           }
327         evas_object_size_hint_min_set(o2, icon_w, icon_h);
328         edje_object_part_swallow(wd->o_check, "e.swallow.icon", o2);
329         evas_object_show(o2);
330         e_widget_sub_object_add(obj, o2);
331         wd->o_icon = o2;
332      }
333 
334    edje_object_size_min_calc(o, &mw, &mh);
335    e_widget_size_min_set(obj, mw, mh);
336    if (wd->valptr)
337      {
338         if (*(wd->valptr)) edje_object_signal_emit(o, "e,state,checked", "e");
339      }
340 
341    e_widget_sub_object_add(obj, o);
342    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_wid_focus_steal, obj);
343    e_widget_resize_object_set(obj, o);
344 
345    return obj;
346 }
347