Revert to the original state
[framework/uifw/elementary.git] / src / lib / elm_button.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Button Button
6  * @ingroup Elementary
7  *
8  * This is a push-button. Press it and run some function. It can contain
9  * a simple label and icon object.
10  */
11
12 typedef struct _Widget_Data Widget_Data;
13
14 enum
15 {
16    DEFAULT = 0,
17    HIGHLIGHTED,
18    FOCUSED,
19    DISABLED,
20 };
21
22 struct _Widget_Data
23 {
24    Evas_Object *btn, *icon;
25    const char *label;
26    Eina_Bool autorepeat;
27    Eina_Bool repeating;
28    double ar_threshold;
29    double ar_interval;
30    Ecore_Timer *timer;
31    const char *statelabel[4];
32    int statetype[4];
33 };
34
35 static const char *widtype = NULL;
36 static void _del_hook(Evas_Object *obj);
37 static void _theme_hook(Evas_Object *obj);
38 static void _disable_hook(Evas_Object *obj);
39 static void _sizing_eval(Evas_Object *obj);
40 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
41 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
42 static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
43 static void _signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source);
44 static void _signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source);
45 static void _on_focus_hook(void *data, Evas_Object *obj);
46 static void _activate(Evas_Object *obj);
47 static void _activate_hook(Evas_Object *obj);
48 static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
49                              Evas_Callback_Type type, void *event_info);
50
51 static void _set_label(Evas_Object *obj, const char *label);
52 static void _signal_default_text_set(void *data, Evas_Object *obj, const char *emission, const char *source);
53
54 static const char SIG_CLICKED[] = "clicked";
55 static const char SIG_REPEATED[] = "repeated";
56 static const char SIG_UNPRESSED[] = "unpressed";
57 static const Evas_Smart_Cb_Description _signals[] = {
58   {SIG_CLICKED, ""},
59   {SIG_REPEATED, ""},
60   {SIG_UNPRESSED, ""},
61   {NULL, NULL}
62 };
63
64 static Eina_Bool
65 _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
66 {
67    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
68    Evas_Event_Key_Down *ev = event_info;
69    Widget_Data *wd = elm_widget_data_get(obj);
70    if (!wd) return EINA_FALSE;
71    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
72    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
73    if ((strcmp(ev->keyname, "Return")) &&
74        (strcmp(ev->keyname, "KP_Enter")) &&
75        (strcmp(ev->keyname, "space")))
76      return EINA_FALSE;
77    _activate(obj);
78    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
79    edje_object_signal_emit(wd->btn, "elm,anim,activate", "elm");
80    return EINA_TRUE;
81 }
82
83 static void
84 _del_hook(Evas_Object *obj)
85 {
86    Widget_Data *wd = elm_widget_data_get(obj);
87    if (!wd) return;
88    if (wd->label) eina_stringshare_del(wd->label);
89    if (wd->statelabel[DEFAULT]) eina_stringshare_del(wd->statelabel[DEFAULT]);
90    if (wd->statelabel[HIGHLIGHTED]) eina_stringshare_del(wd->statelabel[HIGHLIGHTED]);
91    if (wd->statelabel[FOCUSED]) eina_stringshare_del(wd->statelabel[FOCUSED]);
92    if (wd->statelabel[DISABLED]) eina_stringshare_del(wd->statelabel[DISABLED]);
93    free(wd);
94 }
95
96 static void
97 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
98 {
99    Widget_Data *wd = elm_widget_data_get(obj);
100    if (!wd) return;
101    if (elm_widget_focus_get(obj))
102      {
103         if (wd->statelabel[FOCUSED])
104           {
105              _set_label(obj, wd->statelabel[FOCUSED]);
106           }
107         edje_object_signal_emit(wd->btn, "elm,action,focus", "elm");
108         evas_object_focus_set(wd->btn, EINA_TRUE);
109      }
110    else
111      {
112         if (wd->statelabel[DEFAULT])
113           _set_label(obj, wd->statelabel[DEFAULT]);
114         #if 0
115         else
116           _set_label(obj, wd->label);
117         #endif
118         edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm");
119         evas_object_focus_set(wd->btn, EINA_FALSE);
120      }
121 }
122
123 static void
124 _theme_hook(Evas_Object *obj)
125 {
126    Widget_Data *wd = elm_widget_data_get(obj);
127    const char *str;
128    if (!wd) return;
129    _elm_theme_object_set(obj, wd->btn, "button", "base", elm_widget_style_get(obj));
130    if (wd->icon)
131      edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
132    if (wd->label)
133      edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
134    else
135      edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");  
136    if (wd->icon)
137      edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
138    else
139      edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
140    edje_object_part_text_set(wd->btn, "elm.text", wd->label);
141    if (elm_object_disabled_get(obj))
142      edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
143    edje_object_message_signal_process(wd->btn);
144    edje_object_scale_set(wd->btn, elm_widget_scale_get(obj) * _elm_config->scale);
145    str = edje_object_data_get(wd->btn, "focus_highlight");
146    if ((str) && (!strcmp(str, "on")))
147      elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
148    else
149      elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
150    _sizing_eval(obj);
151 }
152
153 static void
154 _disable_hook(Evas_Object *obj)
155 {
156    Widget_Data *wd = elm_widget_data_get(obj);
157    if (!wd) return;
158    if (elm_widget_disabled_get(obj))
159      {
160         if (wd->statelabel[DISABLED] )
161           {
162              _set_label(obj, wd->statelabel[DISABLED]);
163           }
164         edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
165      }
166    else
167      {
168         if (wd->statelabel[DEFAULT])
169           _set_label(obj, wd->statelabel[DEFAULT]);
170         #if 0
171         else
172           _set_label(obj, wd->label);
173         #endif
174         edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
175      }
176 }
177
178 static void
179 _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
180 {
181    Widget_Data *wd = elm_widget_data_get(obj);
182    if (!wd) return;
183    edje_object_signal_emit(wd->btn, emission, source);
184 }
185
186 static void
187 _signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
188 {
189    Widget_Data *wd = elm_widget_data_get(obj);
190    if (!wd) return;
191    edje_object_signal_callback_add(wd->btn, emission, source, func_cb, data);
192 }
193
194 static void
195 _signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
196 {
197    Widget_Data *wd = elm_widget_data_get(obj);
198    edje_object_signal_callback_del_full(wd->btn, emission, source, func_cb,
199                                         data);
200 }
201
202 static void
203 _sizing_eval(Evas_Object *obj)
204 {
205    Widget_Data *wd = elm_widget_data_get(obj);
206    Evas_Coord minw = -1, minh = -1;
207    Evas_Coord w, h;
208
209    if (!wd) return;
210    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
211    edje_object_size_min_restricted_calc(wd->btn, &minw, &minh, minw, minh);
212    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
213    //Commenting to sync with open source and able to resize based on text change
214    evas_object_size_hint_min_get(obj, &w, &h);
215    //if (w > minw) minw = w;
216    if (h > minh) minh = h;
217
218    evas_object_size_hint_min_set(obj, minw, minh);
219 }
220
221 static void
222 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
223 {
224    Widget_Data *wd = elm_widget_data_get(data);
225    if (!wd) return;
226    if (obj != wd->icon) return;
227    _sizing_eval(data);
228 }
229
230 static void
231 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
232 {
233    Widget_Data *wd = elm_widget_data_get(obj);
234    Evas_Object *sub = event_info;
235    if (!wd) return;
236    if (sub == wd->icon)
237      {
238         edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
239         evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
240                                        _changed_size_hints, obj);
241         wd->icon = NULL;
242         edje_object_message_signal_process(wd->btn);
243         _sizing_eval(obj);
244      }
245 }
246
247 static void
248 _activate(Evas_Object *obj)
249 {
250    Widget_Data *wd = elm_widget_data_get(obj);
251    if (!wd) return;
252    if (wd->timer)
253      {
254         ecore_timer_del(wd->timer);
255         wd->timer = NULL;
256      }
257    wd->repeating = EINA_FALSE;
258    evas_object_smart_callback_call(obj, SIG_CLICKED, NULL);
259 }
260
261 static void
262 _activate_hook(Evas_Object *obj)
263 {
264    _activate(obj);
265 }
266
267 static void
268 _signal_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
269 {
270    _activate(data);
271 }
272
273 static Eina_Bool
274 _autorepeat_send(void *data)
275 {
276    Widget_Data *wd = elm_widget_data_get(data);
277    if (!wd) return ECORE_CALLBACK_CANCEL;
278
279    evas_object_smart_callback_call(data, SIG_REPEATED, NULL);
280    if (!wd->repeating)
281      {
282         wd->timer = NULL;
283         return ECORE_CALLBACK_CANCEL;
284      }
285
286    return ECORE_CALLBACK_RENEW;
287 }
288
289 static Eina_Bool
290 _autorepeat_initial_send(void *data)
291 {
292    Widget_Data *wd = elm_widget_data_get(data);
293    if (!wd) return ECORE_CALLBACK_CANCEL;
294
295    if (wd->timer) ecore_timer_del(wd->timer);
296    wd->repeating = EINA_TRUE;
297    _autorepeat_send(data);
298    wd->timer = ecore_timer_add(wd->ar_interval, _autorepeat_send, data);
299
300    return ECORE_CALLBACK_CANCEL;
301 }
302
303 static void
304 _signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
305 {
306    Widget_Data *wd = elm_widget_data_get(data);
307    if (!wd) return;
308
309    if (wd->statelabel[HIGHLIGHTED])
310      {
311         _set_label(data, wd->statelabel[HIGHLIGHTED]);
312      }
313    if ((wd->autorepeat) && (!wd->repeating))
314      {
315         if (wd->ar_threshold <= 0.0)
316           _autorepeat_initial_send(data); /* call immediately */
317         else
318           wd->timer = ecore_timer_add(wd->ar_threshold, _autorepeat_initial_send, data);
319      }
320 }
321
322 static void
323 _signal_default_text_set(void *data, Evas_Object *obj, const char *emission, const char *source)
324 {
325    Widget_Data *wd = elm_widget_data_get(data);
326    if (!wd) return;
327    if (wd->statelabel[DEFAULT])
328      _set_label(data, wd->statelabel[DEFAULT]);
329    #if 0
330    else
331      _set_label(data, wd->label);
332    #endif
333    return;
334 }
335
336 static void
337 _signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
338 {
339    Widget_Data *wd = elm_widget_data_get(data);
340    if (!wd) return;
341    if (wd->statelabel[DEFAULT])
342      _set_label(data, wd->statelabel[DEFAULT]);
343 #if 0
344    else
345      _set_label(data, wd->label);
346 #endif
347
348    if (wd->timer)
349      {
350         ecore_timer_del(wd->timer);
351         wd->timer = NULL;
352      }
353    wd->repeating = EINA_FALSE;
354    evas_object_smart_callback_call(data, SIG_UNPRESSED, NULL);
355 }
356
357 /**
358  * Add a new button to the parent
359  * @param[in] parent The parent object
360  * @return The new object or NULL if it cannot be created
361  *
362  * @ingroup Button
363  */
364 EAPI Evas_Object *
365 elm_button_add(Evas_Object *parent)
366 {
367    Evas_Object *obj;
368    Evas *e;
369    Widget_Data *wd;
370
371    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
372
373    wd = ELM_NEW(Widget_Data);
374    e = evas_object_evas_get(parent);
375    if (!e) return NULL;
376    obj = elm_widget_add(e);
377    ELM_SET_WIDTYPE(widtype, "button");
378    elm_widget_type_set(obj, "button");
379    elm_widget_sub_object_add(parent, obj);
380    elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
381    elm_widget_data_set(obj, wd);
382    elm_widget_del_hook_set(obj, _del_hook);
383    elm_widget_theme_hook_set(obj, _theme_hook);
384    elm_widget_disable_hook_set(obj, _disable_hook);
385    elm_widget_can_focus_set(obj, EINA_TRUE);
386    elm_widget_activate_hook_set(obj, _activate_hook);
387    elm_widget_event_hook_set(obj, _event_hook);
388    elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
389    elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
390    elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
391
392    wd->btn = edje_object_add(e);
393    _elm_theme_object_set(obj, wd->btn, "button", "base", "default");
394    wd->statetype[DEFAULT] = 0;
395    wd->statetype[HIGHLIGHTED] = 0;
396    wd->statetype[FOCUSED] = 0;
397    wd->statetype[DISABLED] = 0;
398    wd->statelabel[DEFAULT] = 0;
399    wd->statelabel[HIGHLIGHTED] = 0;
400    wd->statelabel[FOCUSED] = 0;
401    wd->statelabel[DISABLED] = 0;
402    edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
403                                    _signal_clicked, obj);
404    edje_object_signal_callback_add(wd->btn, "elm,action,press", "",
405                                    _signal_pressed, obj);
406    edje_object_signal_callback_add(wd->btn, "elm,action,unpress", "",
407                                    _signal_unpressed, obj);
408    edje_object_signal_callback_add(wd->btn, "elm,action,default,text,set", "",
409                                    _signal_default_text_set, obj);
410    elm_widget_resize_object_set(obj, wd->btn);
411
412    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
413
414    _theme_hook(obj);
415
416    // TODO: convert Elementary to subclassing of Evas_Smart_Class
417    // TODO: and save some bytes, making descriptions per-class and not instance!
418    evas_object_smart_callbacks_descriptions_set(obj, _signals);
419    return obj;
420 }
421
422 /**
423  * Set the label used in the button
424  *
425  * @param[in] obj The button object
426  * @param[in] label The text will be written on the button
427  *
428  * @ingroup Button
429  */
430 EAPI void
431 elm_button_label_set(Evas_Object *obj, const char *label)
432 {
433    ELM_CHECK_WIDTYPE(obj, widtype);
434    Widget_Data *wd = elm_widget_data_get(obj);
435    if (!wd) return;
436    eina_stringshare_replace(&wd->label, label);
437    if (label)
438      edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
439    else
440      edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
441    edje_object_message_signal_process(wd->btn);
442    edje_object_part_text_set(wd->btn, "elm.text", label);
443    _sizing_eval(obj);
444 }
445
446 static void
447 _set_label(Evas_Object *obj, const char *label)
448 {
449    Widget_Data *wd = elm_widget_data_get(obj);
450
451    edje_object_part_text_set(wd->btn, "elm.text", label);
452    _sizing_eval(obj);
453 }
454 /**
455  * Set the label for each state of button
456  *
457  * @param[in] obj The button object
458  * @param[in] label The text will be written on the button
459  * @param[in] state The state of button
460  *
461  * @ingroup Button
462  */
463 EAPI void
464 elm_button_label_set_for_state(Evas_Object *obj, const char *label, UIControlState state)
465 {
466    Widget_Data *wd = elm_widget_data_get(obj);
467
468    if (!wd) return;
469    if (label == NULL) return;
470
471    if (state == UIControlStateDefault)
472      {
473         wd->statetype[DEFAULT] = UIControlStateDefault;
474         eina_stringshare_replace(&wd->statelabel[DEFAULT], label);
475         return;
476      }
477    if (state == UIControlStateHighlighted)
478      {
479         wd->statetype[HIGHLIGHTED] = UIControlStateHighlighted;
480         eina_stringshare_replace(&wd->statelabel[HIGHLIGHTED], label);
481         return;
482      }
483    if (state == UIControlStateFocused)
484      {
485         wd->statetype[FOCUSED] = UIControlStateFocused;
486         eina_stringshare_replace(&wd->statelabel[FOCUSED], label);
487         return;
488      }
489    if (state == UIControlStateDisabled)
490      {
491         wd->statetype[DISABLED] = UIControlStateDisabled;
492         eina_stringshare_replace(&wd->statelabel[DISABLED], label);
493         return;
494      }
495 }
496
497 /**
498  * Get the label of button
499  *
500  * @param[in] obj The button object
501  * @return The title of button
502  *
503  * @ingroup Button
504  */
505 EAPI const char *
506 elm_button_label_get(const Evas_Object *obj)
507 {
508    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
509    Widget_Data *wd = elm_widget_data_get(obj);
510    if (!wd) return NULL;
511    return wd->label;
512 }
513 /**
514  * Get the label of button for each state
515  *
516  * @param[in] obj The button object
517  * @param[in] state The state of button
518  * @return The title of button for state
519  *
520  * @ingroup Button
521  */
522 EAPI const char*
523 elm_button_label_get_for_state(const Evas_Object *obj, UIControlState state)
524 {
525    Widget_Data *wd = elm_widget_data_get(obj);
526    if (!wd) return NULL;
527
528    if (state == UIControlStateDefault)
529      return wd->statelabel[DEFAULT];
530    else if (state == UIControlStateHighlighted)
531      return wd->statelabel[HIGHLIGHTED];
532    else if (state == UIControlStateFocused)
533      return wd->statelabel[FOCUSED];
534    else if (state == UIControlStateDisabled)
535      return wd->statelabel[DISABLED];
536    else
537      return NULL;
538 }
539
540 /**
541  * Set the icon used for the button
542  *
543  * Once the icon object is set, a previously set one will be deleted
544  * If you want to keep that old content object, use the
545  * elm_button_icon_unset() function. 
546  *
547  * @param[in] obj The button object
548  * @param[in] icon The image for the button
549  *
550  * @ingroup Button
551  */
552 EAPI void
553 elm_button_icon_set(Evas_Object *obj, Evas_Object *icon)
554 {
555    ELM_CHECK_WIDTYPE(obj, widtype);
556    Widget_Data *wd = elm_widget_data_get(obj);
557    if (!wd) return;
558    if (wd->icon == icon) return;
559    if (wd->icon) evas_object_del(wd->icon);
560    wd->icon = icon;
561    if (icon)
562      {
563         elm_widget_sub_object_add(obj, icon);
564         evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
565                                        _changed_size_hints, obj);
566         edje_object_part_swallow(wd->btn, "elm.swallow.content", icon);
567         edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
568         edje_object_message_signal_process(wd->btn);
569      }
570    _sizing_eval(obj);
571 }
572
573 /**
574  * Get the icon used for the button
575  *
576  * Return the icon object which is set for this widget.
577  * @param[in] obj The button object
578  * @return The icon object that is being used
579  *
580  * @ingroup Button
581  */
582 EAPI Evas_Object *
583 elm_button_icon_get(const Evas_Object *obj)
584 {
585    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
586    Widget_Data *wd = elm_widget_data_get(obj);
587    if (!wd) return NULL;
588    return wd->icon;
589 }
590
591 /**
592  * Unset the icon used for the button
593  *
594  * Unparent and return the icon object which was set for this widget.
595  *
596  * @param[in] obj The button object
597  * @return The icon object that was being used
598  *
599  * @ingroup Button
600  */
601 EAPI Evas_Object *
602 elm_button_icon_unset(Evas_Object *obj)
603 {
604    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
605    Widget_Data *wd = elm_widget_data_get(obj);
606    if (!wd) return NULL;
607    if (!wd->icon) return NULL;
608    Evas_Object *icon = wd->icon;
609    elm_widget_sub_object_del(obj, wd->icon);
610    edje_object_part_unswallow(wd->btn, wd->icon);
611    wd->icon = NULL;
612    return icon;
613 }
614
615 /**
616  * Turn on/off the autorepeat event generated when the user keeps pressing on the button
617  *
618  * @param[in] obj The button object
619  * @param[in] on  A bool to turn on/off the event
620  *
621  * @ingroup Button
622  */
623 EAPI void
624 elm_button_autorepeat_set(Evas_Object *obj, Eina_Bool on)
625 {
626    ELM_CHECK_WIDTYPE(obj, widtype);
627    Widget_Data *wd = elm_widget_data_get(obj);
628    if (!wd) return;
629    if (wd->timer)
630      {
631         ecore_timer_del(wd->timer);
632         wd->timer = NULL;
633      }
634    wd->autorepeat = on;
635    wd->repeating = EINA_FALSE;
636 }
637
638 /**
639  * Get if autorepeat event is on
640  *
641  * @param obj The button object
642  * @return If autorepeat is on
643  *
644  * @ingroup Button
645  */
646 EAPI Eina_Bool
647 elm_button_autorepeat_get(const Evas_Object *obj)
648 {
649    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
650    Widget_Data *wd = elm_widget_data_get(obj);
651    if (!wd) return EINA_FALSE;
652    return wd->autorepeat;
653 }
654
655 /**
656  * Set the initial timeout before the autorepeat event is generated
657  *
658  * @param[in] obj The button object
659  * @param[in] t   Timeout
660  *
661  * @ingroup Button
662  */
663 EAPI void
664 elm_button_autorepeat_initial_timeout_set(Evas_Object *obj, double t)
665 {
666    ELM_CHECK_WIDTYPE(obj, widtype);
667    Widget_Data *wd = elm_widget_data_get(obj);
668    if (!wd) return;
669    if (wd->ar_threshold == t) return;
670    if (wd->timer)
671      {
672         ecore_timer_del(wd->timer);
673         wd->timer = NULL;
674      }
675    wd->ar_threshold = t;
676 }
677
678 /**
679  * Get the initial timeout before the autorepeat event is generated
680  *
681  * @param[in] obj The button object
682  * @return Timeout
683  *
684  * @ingroup Button
685  */
686 EAPI double
687 elm_button_autorepeat_initial_timeout_get(const Evas_Object *obj)
688 {
689    ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
690    Widget_Data *wd = elm_widget_data_get(obj);
691    if (!wd) return 0.0;
692    return wd->ar_threshold;
693 }
694
695 /**
696  * Set the interval between each generated autorepeat event
697  *
698  * @param[in] obj The button object
699  * @param[in] t   Interval
700  *
701  * @ingroup Button
702  */
703 EAPI void
704 elm_button_autorepeat_gap_timeout_set(Evas_Object *obj, double t)
705 {
706    ELM_CHECK_WIDTYPE(obj, widtype);
707    Widget_Data *wd = elm_widget_data_get(obj);
708    if (!wd) return;
709    if (wd->ar_interval == t) return;
710
711    wd->ar_interval = t;
712    if ((wd->repeating) && (wd->timer)) ecore_timer_interval_set(wd->timer, t);
713 }
714
715 /**
716  * Get the interval between each generated autorepeat event
717  *
718  * @param[in] obj The button object
719  * @return Interval
720  *
721  * @ingroup Button
722  */
723 EAPI double
724 elm_button_autorepeat_gap_timeout_get(const Evas_Object *obj)
725 {
726    ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
727    Widget_Data *wd = elm_widget_data_get(obj);
728    if (!wd) return 0.0;
729    return wd->ar_interval;
730 }