check, colorselector, calendar, diskselector: apply key binding
[platform/upstream/elementary.git] / src / lib / elm_check.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include <Elementary.h>
6 #include "elm_priv.h"
7 #include "elm_widget_check.h"
8 #include "elm_widget_layout.h"
9
10 #define MY_CLASS ELM_OBJ_CHECK_CLASS
11
12 #define MY_CLASS_NAME "Elm_Check"
13 #define MY_CLASS_NAME_LEGACY "elm_check"
14
15 static const Elm_Layout_Part_Alias_Description _content_aliases[] =
16 {
17    {"icon", "elm.swallow.content"},
18    {NULL, NULL}
19 };
20
21 static const Elm_Layout_Part_Alias_Description _text_aliases[] =
22 {
23    {"default", "elm.text"},
24    {"on", "elm.ontext"},
25    {"off", "elm.offtext"},
26    {NULL, NULL}
27 };
28
29 static const char SIG_CHANGED[] = "changed";
30
31 /* smart callbacks coming from elm check objects: */
32 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
33    {SIG_CHANGED, ""},
34    {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
35    {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
36    {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
37    {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
38    {NULL, NULL}
39 };
40
41 static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params);
42
43 static const Elm_Action key_actions[] = {
44    {"activate", _key_action_activate},
45    {NULL, NULL}
46 };
47
48 static void
49 _activate(Evas_Object *obj)
50 {
51    ELM_CHECK_DATA_GET(obj, sd);
52
53    sd->state = !sd->state;
54    if (sd->statep) *sd->statep = sd->state;
55    if (sd->state)
56      {
57         elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
58         if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
59              _elm_access_say(E_("State: On"));
60      }
61    else
62      {
63         elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
64         if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
65              _elm_access_say(E_("State: Off"));
66      }
67
68    evas_object_smart_callback_call(obj, SIG_CHANGED, NULL);
69 }
70
71 /* FIXME: replicated from elm_layout just because check's icon spot
72  * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we
73  * can changed the theme API */
74 static void
75 _icon_signal_emit(Evas_Object *obj)
76 {
77    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
78    char buf[64];
79
80    snprintf(buf, sizeof(buf), "elm,state,icon,%s",
81             elm_layout_content_get(obj, "icon") ? "visible" : "hidden");
82
83    elm_layout_signal_emit(obj, buf, "elm");
84    edje_object_message_signal_process(wd->resize_obj);
85 }
86
87 /* FIXME: replicated from elm_layout just because check's icon spot
88  * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we
89  * can changed the theme API */
90 EOLIAN static Eina_Bool
91 _elm_check_elm_widget_sub_object_del(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED, Evas_Object *sobj)
92 {
93    Eina_Bool int_ret = EINA_FALSE;
94
95    eo_do_super(obj, MY_CLASS, elm_obj_widget_sub_object_del(sobj, &int_ret));
96    if (!int_ret) return EINA_FALSE;
97
98    _icon_signal_emit(obj);
99
100    eo_do(obj, elm_obj_layout_sizing_eval());
101
102    return EINA_TRUE;
103 }
104
105 EOLIAN static Eina_Bool
106 _elm_check_elm_widget_activate(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNUSED, Elm_Activate act)
107 {
108    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
109    if (act != ELM_ACTIVATE_DEFAULT) return EINA_FALSE;
110
111    _activate(obj);
112
113    return EINA_TRUE;
114 }
115
116 /* FIXME: replicated from elm_layout just because check's icon spot
117  * is elm.swallow.content, not elm.swallow.icon. Fix that whenever we
118  * can changed the theme API */
119 EOLIAN static Eina_Bool
120 _elm_check_elm_container_content_set(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED, const char *part, Evas_Object *content)
121 {
122    Eina_Bool int_ret = EINA_FALSE;
123
124    eo_do_super(obj, MY_CLASS, elm_obj_container_content_set(part, content, &int_ret));
125    if (!int_ret) return EINA_FALSE;
126
127    _icon_signal_emit(obj);
128
129    eo_do(obj, elm_obj_layout_sizing_eval());
130
131    return EINA_TRUE;
132 }
133
134 EOLIAN static void
135 _elm_check_elm_layout_sizing_eval(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED)
136 {
137    Evas_Coord minw = -1, minh = -1;
138    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
139
140    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
141    edje_object_size_min_restricted_calc
142      (wd->resize_obj, &minw, &minh, minw, minh);
143    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
144    evas_object_size_hint_min_set(obj, minw, minh);
145    evas_object_size_hint_max_set(obj, -1, -1);
146 }
147
148 static Eina_Bool
149 _key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED)
150 {
151    _activate(obj);
152    return EINA_TRUE;
153 }
154
155 EOLIAN static Eina_Bool
156 _elm_check_elm_widget_event(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info)
157 {
158    (void) src;
159    Evas_Event_Key_Down *ev = event_info;
160
161    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
162    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
163    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
164
165    if (!_elm_config_key_binding_call(obj, ev, key_actions))
166      return EINA_FALSE;
167
168    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
169    return EINA_TRUE;
170 }
171
172 EOLIAN static Eina_Bool
173 _elm_check_elm_widget_theme_apply(Eo *obj, Elm_Check_Data *sd)
174 {
175    Eina_Bool int_ret = EINA_FALSE;
176
177    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
178
179    eo_do_super(obj, MY_CLASS, elm_obj_widget_theme_apply(&int_ret));
180    if (!int_ret) return EINA_FALSE;
181
182    if (!sd->state) elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
183    else elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
184
185    edje_object_message_signal_process(wd->resize_obj);
186
187    /* FIXME: replicated from elm_layout just because check's icon spot
188     * is elm.swallow.content, not elm.swallow.icon. Fix that whenever
189     * we can changed the theme API */
190    _icon_signal_emit(obj);
191
192    eo_do(obj, elm_obj_layout_sizing_eval());
193
194    return EINA_TRUE;
195 }
196
197 static char *
198 _access_info_cb(void *data EINA_UNUSED, Evas_Object *obj)
199 {
200    const char *txt = elm_widget_access_info_get(obj);
201
202    if (!txt) txt = elm_layout_text_get(obj, NULL);
203    if (txt) return strdup(txt);
204
205    return NULL;
206 }
207
208 static char *
209 _access_state_cb(void *data, Evas_Object *obj)
210 {
211    Elm_Check_Data *sd = eo_data_scope_get(data, MY_CLASS);
212    const char *on_text, *off_text;
213
214    if (elm_widget_disabled_get(obj))
215      return strdup(E_("State: Disabled"));
216    if (sd->state)
217      {
218         on_text = elm_layout_text_get(data, "on");
219
220         if (on_text)
221           {
222              char buf[1024];
223
224              snprintf(buf, sizeof(buf), "%s: %s", E_("State"), on_text);
225              return strdup(buf);
226           }
227         else
228           return strdup(E_("State: On"));
229      }
230
231    off_text = elm_layout_text_get(data, "off");
232
233    if (off_text)
234      {
235         char buf[1024];
236
237         snprintf(buf, sizeof(buf), "%s: %s", E_("State"), off_text);
238         return strdup(buf);
239      }
240    return strdup(E_("State: Off"));
241 }
242
243 static void
244 _on_check_off(void *data,
245               Evas_Object *o EINA_UNUSED,
246               const char *emission EINA_UNUSED,
247               const char *source EINA_UNUSED)
248 {
249    Evas_Object *obj = data;
250
251    ELM_CHECK_DATA_GET(obj, sd);
252
253    sd->state = EINA_FALSE;
254    if (sd->statep) *sd->statep = sd->state;
255
256    elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
257    evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
258 }
259
260 static void
261 _on_check_on(void *data,
262              Evas_Object *o EINA_UNUSED,
263              const char *emission EINA_UNUSED,
264              const char *source EINA_UNUSED)
265 {
266    Evas_Object *obj = data;
267
268    ELM_CHECK_DATA_GET(obj, sd);
269
270    sd->state = EINA_TRUE;
271    if (sd->statep) *sd->statep = sd->state;
272    elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
273    evas_object_smart_callback_call(data, SIG_CHANGED, NULL);
274 }
275
276 static void
277 _on_check_toggle(void *data,
278                  Evas_Object *o EINA_UNUSED,
279                  const char *emission EINA_UNUSED,
280                  const char *source EINA_UNUSED)
281 {
282    _activate(data);
283 }
284
285 EOLIAN static void
286 _elm_check_evas_smart_add(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED)
287 {
288    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
289
290    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
291    elm_widget_sub_object_parent_add(obj);
292
293    edje_object_signal_callback_add
294      (wd->resize_obj, "elm,action,check,on", "*",
295      _on_check_on, obj);
296    edje_object_signal_callback_add
297      (wd->resize_obj, "elm,action,check,off", "*",
298      _on_check_off, obj);
299    edje_object_signal_callback_add
300      (wd->resize_obj, "elm,action,check,toggle", "*",
301      _on_check_toggle, obj);
302
303    _elm_access_object_register(obj, wd->resize_obj);
304    _elm_access_text_set
305      (_elm_access_info_get(obj), ELM_ACCESS_TYPE, E_("Check"));
306    _elm_access_callback_set
307      (_elm_access_info_get(obj), ELM_ACCESS_INFO, _access_info_cb, obj);
308    _elm_access_callback_set
309      (_elm_access_info_get(obj), ELM_ACCESS_STATE, _access_state_cb, obj);
310
311    elm_widget_can_focus_set(obj, EINA_TRUE);
312
313    if (!elm_layout_theme_set(obj, "check", "base", elm_widget_style_get(obj)))
314      CRI("Failed to set layout!");
315
316    elm_layout_sizing_eval(obj);
317 }
318
319 EOLIAN static const Elm_Layout_Part_Alias_Description*
320 _elm_check_elm_layout_content_aliases_get(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNUSED)
321 {
322    return _content_aliases;
323 }
324
325 EOLIAN static const Elm_Layout_Part_Alias_Description*
326 _elm_check_elm_layout_text_aliases_get(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNUSED)
327 {
328    return _text_aliases;
329 }
330
331 EAPI Evas_Object *
332 elm_check_add(Evas_Object *parent)
333 {
334    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
335    Evas_Object *obj = eo_add(MY_CLASS, parent);
336    eo_unref(obj);
337    return obj;
338 }
339
340 EOLIAN static void
341 _elm_check_eo_base_constructor(Eo *obj, Elm_Check_Data *_pd EINA_UNUSED)
342 {
343    eo_do_super(obj, MY_CLASS, eo_constructor());
344    eo_do(obj,
345          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
346          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks, NULL));
347 }
348
349 EOLIAN static void
350 _elm_check_state_set(Eo *obj, Elm_Check_Data *sd, Eina_Bool state)
351 {
352    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
353
354    if (state != sd->state)
355      {
356         sd->state = state;
357         if (sd->statep) *sd->statep = sd->state;
358         if (sd->state)
359           elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
360         else
361           elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
362      }
363
364    edje_object_message_signal_process(wd->resize_obj);
365 }
366
367 EOLIAN static Eina_Bool
368 _elm_check_state_get(Eo *obj EINA_UNUSED, Elm_Check_Data *sd)
369 {
370    return sd->state;
371 }
372
373 EOLIAN static void
374 _elm_check_state_pointer_set(Eo *obj, Elm_Check_Data *sd, Eina_Bool *statep)
375 {
376    if (statep)
377      {
378         sd->statep = statep;
379         if (*sd->statep != sd->state)
380           {
381              sd->state = *sd->statep;
382              if (sd->state)
383                elm_layout_signal_emit(obj, "elm,state,check,on", "elm");
384              else
385                elm_layout_signal_emit(obj, "elm,state,check,off", "elm");
386           }
387      }
388    else
389      sd->statep = NULL;
390 }
391
392 EOLIAN static Eina_Bool
393 _elm_check_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNUSED)
394 {
395    return EINA_FALSE;
396 }
397
398 EOLIAN static Eina_Bool
399 _elm_check_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Check_Data *_pd EINA_UNUSED)
400 {
401    return EINA_FALSE;
402 }
403
404 static void
405 _elm_check_class_constructor(Eo_Class *klass)
406 {
407    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
408 }
409
410 #include "elm_check.eo.c"