elementary/map - map supports language,changed
[framework/uifw/elementary.git] / src / lib / elm_check.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "elm_widget_check.h"
4
5 #define _TIZEN_
6
7 EAPI const char ELM_CHECK_SMART_NAME[] = "elm_check";
8
9 static const Elm_Layout_Part_Alias_Description _content_aliases[] =
10 {
11    {"icon", "elm.swallow.content"},
12    {NULL, NULL}
13 };
14
15 static const Elm_Layout_Part_Alias_Description _text_aliases[] =
16 {
17    {"default", "elm.text"},
18    {"on", "elm.ontext"},
19    {"off", "elm.offtext"},
20    {NULL, NULL}
21 };
22
23 static const char SIG_CHANGED[] = "changed";
24
25 /* smart callbacks coming from elm check objects: */
26 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
27    {SIG_CHANGED, ""},
28    {NULL, NULL}
29 };
30
31 EVAS_SMART_SUBCLASS_NEW
32   (ELM_CHECK_SMART_NAME, _elm_check, Elm_Check_Smart_Class,
33   Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
34
35 static void
36 _activate(Evas_Object *obj)
37 {
38    ELM_CHECK_DATA_GET(obj, sd);
39
40    sd->state = !sd->state;
41    if (sd->statep) *sd->statep = sd->state;
42    if (sd->state)
43      {
44         elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
45         if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
46              _elm_access_say(E_("State: On"));
47      }
48    else
49      {
50         elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
51         if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
52              _elm_access_say(E_("State: Off"));
53      }
54
55    evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
56 }
57
58 /* FIXME: replicated from elm_layout just because check's icon spot
59  * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we
60  * can changed the theme API */
61 static void
62 _icon_signal_emit(Evas_Object *obj)
63 {
64    char buf[64];
65
66    snprintf(buf, sizeof(buf), "elm,state,icon,%s",
67             elm_layout_content_get(obj, "icon") ? "visible" : "hidden");
68
69    elm_layout_signal_emit(obj, buf, "elm");
70 }
71
72 /* FIXME: replicated from elm_layout just because check's icon spot
73  * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we
74  * can changed the theme API */
75 static Eina_Bool
76 _elm_check_smart_sub_object_del(Evas_Object *obj,
77                                  Evas_Object *sobj)
78 {
79    if (!ELM_WIDGET_CLASS(_elm_check_parent_sc)->sub_object_del(obj, sobj))
80      return EINA_FALSE;
81
82    _icon_signal_emit(obj);
83
84    return EINA_TRUE;
85 }
86
87 static Eina_Bool
88 _elm_check_smart_activate(Evas_Object *obj, Elm_Activate act)
89 {
90    if (act != ELM_ACTIVATE_DEFAULT) return EINA_FALSE;
91
92    _activate(obj);
93
94    return EINA_TRUE;
95 }
96
97 /* FIXME: replicated from elm_layout just because check's icon spot
98  * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we
99  * can changed the theme API */
100 static Eina_Bool
101 _elm_check_smart_content_set(Evas_Object *obj,
102                               const char *part,
103                               Evas_Object *content)
104 {
105    if (!ELM_CONTAINER_CLASS(_elm_check_parent_sc)->content_set
106          (obj, part, content))
107      return EINA_FALSE;
108
109    _icon_signal_emit(obj);
110
111    return EINA_TRUE;
112 }
113
114 static void
115 _elm_check_smart_sizing_eval(Evas_Object *obj)
116 {
117    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
118
119    ELM_CHECK_DATA_GET(obj, sd);
120
121    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
122    edje_object_size_min_restricted_calc
123      (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
124    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
125    evas_object_size_hint_min_set(obj, minw, minh);
126    evas_object_size_hint_max_set(obj, maxw, maxh);
127 }
128
129 static Eina_Bool
130 _elm_check_smart_event(Evas_Object *obj,
131                        Evas_Object *src __UNUSED__,
132                        Evas_Callback_Type type,
133                        void *event_info)
134 {
135    Evas_Event_Key_Down *ev = event_info;
136
137    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
138
139    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
140
141    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
142
143    if ((strcmp(ev->keyname, "Return")) &&
144        (strcmp(ev->keyname, "KP_Enter")) &&
145        (strcmp(ev->keyname, "space")))
146      return EINA_FALSE;
147
148    _activate(obj);
149    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
150
151    return EINA_TRUE;
152 }
153
154 static Eina_Bool
155 _elm_check_smart_theme(Evas_Object *obj)
156 {
157    ELM_CHECK_DATA_GET(obj, sd);
158
159    if (!ELM_WIDGET_CLASS(_elm_check_parent_sc)->theme(obj)) return EINA_FALSE;
160
161    if (!sd->state) elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
162    else elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
163
164    edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
165
166    /* FIXME: replicated from elm_layout just because check's icon spot
167     * is elm.swallow.content, not elm.swallow.icon. Fix that whenever
168     * we can changed the theme API */
169    _icon_signal_emit(obj);
170
171    elm_layout_sizing_eval(obj);
172
173    return EINA_TRUE;
174 }
175
176 static char *
177 _access_info_cb(void *data __UNUSED__, Evas_Object *obj)
178 {
179    const char *txt = elm_widget_access_info_get(obj);
180
181    if (!txt) txt = elm_layout_text_get(obj, NULL);
182    if (txt) return strdup(txt);
183
184    return NULL;
185 }
186
187 static char *
188 _access_state_cb(void *data, Evas_Object *obj)
189 {
190    Elm_Check_Smart_Data *sd = data;
191    const char *on_text, *off_text;
192
193    if (elm_widget_disabled_get(obj))
194      return strdup(E_("State: Disabled"));
195    if (sd->state)
196      {
197         on_text = elm_layout_text_get(ELM_WIDGET_DATA(sd)->obj, "on");
198
199         if (on_text)
200           {
201              char buf[1024];
202
203              snprintf(buf, sizeof(buf), "%s: %s", E_("State"), on_text);
204              return strdup(buf);
205           }
206         else
207           return strdup(E_("State: On"));
208      }
209
210    off_text = elm_layout_text_get(ELM_WIDGET_DATA(sd)->obj, "off");
211
212    if (off_text)
213      {
214         char buf[1024];
215
216         snprintf(buf, sizeof(buf), "%s: %s", E_("State"), off_text);
217         return strdup(buf);
218      }
219    return strdup(E_("State: Off"));
220 }
221
222 static void
223 _on_check_off(void *data,
224               Evas_Object *o __UNUSED__,
225               const char *emission __UNUSED__,
226               const char *source __UNUSED__)
227 {
228    Evas_Object *obj = data;
229
230    ELM_CHECK_DATA_GET(obj, sd);
231
232    sd->state = EINA_FALSE;
233    if (sd->statep) *sd->statep = sd->state;
234
235    elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
236    evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
237 }
238
239 static void
240 _on_check_on(void *data,
241              Evas_Object *o __UNUSED__,
242              const char *emission __UNUSED__,
243              const char *source __UNUSED__)
244 {
245    Evas_Object *obj = data;
246
247    ELM_CHECK_DATA_GET(obj, sd);
248
249    sd->state = EINA_TRUE;
250    if (sd->statep) *sd->statep = sd->state;
251    elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
252    evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
253 }
254
255 static void
256 _on_check_toggle(void *data,
257                  Evas_Object *o __UNUSED__,
258                  const char *emission __UNUSED__,
259                  const char *source __UNUSED__)
260 {
261    _activate(data);
262 }
263
264 #ifdef _TIZEN_
265 static void _check_drag_start(void *data,
266                               Evas_Object *o __UNUSED__,
267                               const char *emission __UNUSED__,
268                               const char *source __UNUSED__)
269 {
270    Evas_Object *obj = data;
271
272    elm_widget_scroll_freeze_push(obj);
273 }
274
275 static void _check_drag_stop(void *data,
276                              Evas_Object *o __UNUSED__,
277                              const char *emission __UNUSED__,
278                              const char *source __UNUSED__)
279 {
280    Evas_Object *obj = data;
281
282    elm_widget_scroll_freeze_pop(obj);
283 }
284 #endif
285
286 static void
287 _elm_check_smart_add(Evas_Object *obj)
288 {
289    EVAS_SMART_DATA_ALLOC(obj, Elm_Check_Smart_Data);
290
291    ELM_WIDGET_CLASS(_elm_check_parent_sc)->base.add(obj);
292
293    edje_object_signal_callback_add
294      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,on", "",
295      _on_check_on, obj);
296    edje_object_signal_callback_add
297      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,off", "",
298      _on_check_off, obj);
299    edje_object_signal_callback_add
300      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,toggle", "",
301      _on_check_toggle, obj);
302
303    #ifdef _TIZEN_
304    edje_object_signal_callback_add
305      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,drag,start", "",
306      _check_drag_start, obj);
307    edje_object_signal_callback_add
308      (ELM_WIDGET_DATA(priv)->resize_obj, "elm,action,check,drag,stop", "",
309      _check_drag_stop, obj);
310    #endif
311
312    _elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj);
313    _elm_access_text_set
314      (_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("Check"));
315    _elm_access_callback_set
316      (_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, priv);
317    _elm_access_callback_set
318      (_elm_access_object_get(obj), ELM_ACCESS_STATE, _access_state_cb, priv);
319
320    elm_widget_can_focus_set(obj, EINA_TRUE);
321
322    elm_layout_theme_set(obj, "check", "base", elm_widget_style_get(obj));
323    elm_layout_sizing_eval(obj);
324 }
325
326 #ifdef _TIZEN_
327 static void
328 _elm_check_smart_del(Evas_Object *obj)
329 {
330
331    if (0 != elm_widget_scroll_freeze_get(obj))
332      elm_widget_scroll_freeze_pop(obj);
333
334    ELM_WIDGET_CLASS(_elm_check_parent_sc)->base.del(obj);
335 }
336 #endif
337
338 static void
339 _elm_check_smart_set_user(Elm_Check_Smart_Class *sc)
340 {
341    ELM_WIDGET_CLASS(sc)->base.add = _elm_check_smart_add;
342
343    #ifdef _TIZEN_
344    ELM_WIDGET_CLASS(sc)->base.del = _elm_check_smart_del;
345    #endif
346
347    ELM_WIDGET_CLASS(sc)->theme = _elm_check_smart_theme;
348    ELM_WIDGET_CLASS(sc)->event = _elm_check_smart_event;
349    ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_check_smart_sub_object_del;
350    ELM_WIDGET_CLASS(sc)->activate = _elm_check_smart_activate;
351
352    /* not a 'focus chain manager' */
353    ELM_WIDGET_CLASS(sc)->focus_next = NULL;
354    ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
355
356    ELM_CONTAINER_CLASS(sc)->content_set = _elm_check_smart_content_set;
357
358    ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_check_smart_sizing_eval;
359
360    ELM_LAYOUT_CLASS(sc)->content_aliases = _content_aliases;
361    ELM_LAYOUT_CLASS(sc)->text_aliases = _text_aliases;
362 }
363
364 EAPI const Elm_Check_Smart_Class *
365 elm_check_smart_class_get(void)
366 {
367    static Elm_Check_Smart_Class _sc =
368      ELM_CHECK_SMART_CLASS_INIT_NAME_VERSION(ELM_CHECK_SMART_NAME);
369    static const Elm_Check_Smart_Class *class = NULL;
370    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
371
372    if (class)
373      return class;
374
375    _elm_check_smart_set(&_sc);
376    esc->callbacks = _smart_callbacks;
377    class = &_sc;
378
379    return class;
380 }
381
382 EAPI Evas_Object *
383 elm_check_add(Evas_Object *parent)
384 {
385    Evas_Object *obj;
386
387    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
388
389    obj = elm_widget_add(_elm_check_smart_class_new(), parent);
390    if (!obj) return NULL;
391
392    if (!elm_widget_sub_object_add(parent, obj))
393      ERR("could not add %p as sub object of %p", obj, parent);
394
395    return obj;
396 }
397
398 EAPI void
399 elm_check_state_set(Evas_Object *obj,
400                     Eina_Bool state)
401 {
402    ELM_CHECK_CHECK(obj);
403    ELM_CHECK_DATA_GET(obj, sd);
404
405    if (state != sd->state)
406      {
407         sd->state = state;
408         if (sd->statep) *sd->statep = sd->state;
409         if (sd->state)
410           elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
411         else
412           elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
413      }
414
415    edje_object_message_signal_process(ELM_WIDGET_DATA(sd)->resize_obj);
416 }
417
418 EAPI Eina_Bool
419 elm_check_state_get(const Evas_Object *obj)
420 {
421    ELM_CHECK_CHECK(obj) EINA_FALSE;
422    ELM_CHECK_DATA_GET(obj, sd);
423
424    return sd->state;
425 }
426
427 EAPI void
428 elm_check_state_pointer_set(Evas_Object *obj,
429                             Eina_Bool *statep)
430 {
431    ELM_CHECK_CHECK(obj);
432    ELM_CHECK_DATA_GET(obj, sd);
433
434    if (statep)
435      {
436         sd->statep = statep;
437         if (*sd->statep != sd->state)
438           {
439              sd->state = *sd->statep;
440              if (sd->state)
441                elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
442              else
443                elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
444           }
445      }
446    else
447      sd->statep = NULL;
448 }
449
450 #undef _TIZEN_