From: Carsten Haitzler Date: Sun, 24 Jan 2010 01:53:37 +0000 (+0000) Subject: brian's button autorepeat core code. X-Git-Tag: v1.0.0~4849 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6147e14f2a8268a6ea0c01682056779e8d230975;p=platform%2Fupstream%2Felementary.git brian's button autorepeat core code. SVN revision: 45504 --- diff --git a/data/themes/default.edc b/data/themes/default.edc index 1efb6b8..a7b8c29 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -737,6 +737,11 @@ collections { name: "button_click"; signal: "mouse,down,1"; source: "over2"; + action: SIGNAL_EMIT "elm,action,press" ""; + after: "button_click_anim"; + } + program { + name: "button_click_anim"; action: STATE_SET "clicked" 0.0; target: "button_image"; } @@ -744,6 +749,11 @@ collections { name: "button_unclick"; signal: "mouse,up,1"; source: "over2"; + action: SIGNAL_EMIT "elm,action,unpress" ""; + after: "button_unclick_anim"; + } + program { + name: "button_unclick_anim"; action: STATE_SET "default" 0.0; target: "button_image"; } diff --git a/src/bin/test_button.c b/src/bin/test_button.c index 489bebb..f154e77 100644 --- a/src/bin/test_button.c +++ b/src/bin/test_button.c @@ -1,5 +1,17 @@ #include #ifndef ELM_LIB_QUICKLAUNCH +static void +_bt_repeated(void *data, Evas_Object *obj, void *event_info) +{ + static int count; + char buf[16]; + + snprintf(buf, sizeof(buf), "count=%d", count++); + if (count >= 10000) + count = 0; + elm_button_label_set(obj, buf); +} + void test_button(void *data, Evas_Object *obj, void *event_info) { @@ -68,6 +80,10 @@ test_button(void *data, Evas_Object *obj, void *event_info) bt = elm_button_add(win); elm_button_label_set(bt, "Label Only"); elm_box_pack_end(bx, bt); + evas_object_smart_callback_add(bt, "repeated", _bt_repeated, NULL); + elm_button_autorepeat_set(bt, 1); + elm_button_autorepeat_initital_timeout_set(bt, 2.0); + elm_button_autorepeat_gap_timeout_set(bt, 0.5); evas_object_show(bt); ic = elm_icon_add(win); diff --git a/src/lib/elm_button.c b/src/lib/elm_button.c index 1e6443f..ab87d14 100644 --- a/src/lib/elm_button.c +++ b/src/lib/elm_button.c @@ -1,3 +1,7 @@ +/* + * + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ #include #include "elm_priv.h" @@ -14,6 +18,12 @@ struct _Widget_Data { Evas_Object *btn, *icon; const char *label; + + Eina_Bool autorepeat; + Eina_Bool repeating; + double ar_threshold; + double ar_interval; + Ecore_Timer *timer; }; static void _del_hook(Evas_Object *obj); @@ -23,6 +33,8 @@ static void _sizing_eval(Evas_Object *obj); static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _sub_del(void *data, Evas_Object *obj, void *event_info); static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source); +static void _signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source); static void _on_focus_hook(void *data, Evas_Object *obj); static void @@ -124,6 +136,61 @@ _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char * Widget_Data *wd = elm_widget_data_get(data); if (!wd) return; evas_object_smart_callback_call(data, "clicked", NULL); + _signal_unpressed(data, obj, emission, source); /* safe guard when the theme does not emit the 'unpress' signal */ +} + +static int +_autorepeat_send(void *data) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return ECORE_CALLBACK_CANCEL; + + evas_object_smart_callback_call(data, "repeated", NULL); + + return ECORE_CALLBACK_RENEW; +} + +static int +_autorepeat_initial_send(void *data) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return ECORE_CALLBACK_CANCEL; + + _autorepeat_send(data); + wd->timer = ecore_timer_add(wd->ar_interval, _autorepeat_send, data); + wd->repeating = 1; + + return ECORE_CALLBACK_CANCEL; +} + +static void +_signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + + if (wd->autorepeat) + { + if (wd->ar_threshold <= 0.0) + _autorepeat_initial_send(data); /* call immediately */ + else + wd->timer = ecore_timer_add(wd->ar_threshold, _autorepeat_initial_send, data); + } +} + +static void +_signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return; + evas_object_smart_callback_call(data, "unpressed", NULL); + + if (wd->timer) + { + ecore_timer_del(wd->timer); + wd->timer = NULL; + } + wd->repeating = 0; } /** @@ -156,6 +223,10 @@ elm_button_add(Evas_Object *parent) _elm_theme_set(wd->btn, "button", "base", "default"); edje_object_signal_callback_add(wd->btn, "elm,action,click", "", _signal_clicked, obj); + edje_object_signal_callback_add(wd->btn, "elm,action,press", "", + _signal_pressed, obj); + edje_object_signal_callback_add(wd->btn, "elm,action,unpress", "", + _signal_unpressed, obj); elm_widget_resize_object_set(obj, wd->btn); evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); @@ -256,3 +327,81 @@ elm_button_style_set(Evas_Object *obj, const char *style) { elm_widget_style_set(obj, style); } + +/** + * Turn on/off the autorepeat event generated when the user keeps pressing on the button + * + * @param obj The button object + * @param on A bool to turn on/off the event + * + * @ingroup Button + */ +EAPI void +elm_button_autorepeat_set(Evas_Object *obj, Eina_Bool on) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (wd->timer) { + ecore_timer_del(wd->timer); + wd->timer = NULL; + } + wd->autorepeat = on; +} + +/** + * Set the initial timeout before the autorepeat event is generated + * + * @param obj The button object + * @param t Timeout + * + * @ingroup Button + */ +EAPI void +elm_button_autorepeat_initital_timeout_set(Evas_Object *obj, double t) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (wd->ar_threshold == t) + return; + + if (wd->timer) + { + ecore_timer_del(wd->timer); + wd->timer = NULL; + } + + wd->ar_threshold = t; +} + +/** + * Set the interval between each generated autorepeat event + * + * @param obj The button object + * @param t Interval + * + * @ingroup Button + */ +EAPI void +elm_button_autorepeat_gap_timeout_set(Evas_Object *obj, double t) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + + if (wd->ar_interval == t) + return; + + if (wd->timer) + { + ecore_timer_del(wd->timer); + wd->timer = NULL; + } + + wd->ar_interval = t; + if (wd->repeating) + { + wd->timer = ecore_timer_add(t, _autorepeat_send, obj); + } +} +