2008-09-29 23:58:56 -07:00
|
|
|
#include <Elementary.h>
|
|
|
|
#include "elm_priv.h"
|
|
|
|
|
2009-09-17 15:39:18 -07:00
|
|
|
/**
|
|
|
|
* @defgroup Button Button
|
|
|
|
*
|
|
|
|
* This is a push-button. Press it and run some function. It can contain
|
|
|
|
* a simple label and icon object.
|
|
|
|
*/
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
typedef struct _Widget_Data Widget_Data;
|
2008-09-29 23:58:56 -07:00
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
struct _Widget_Data
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2009-09-26 10:39:29 -07:00
|
|
|
Evas_Object *btn, *icon;
|
2008-11-14 22:09:04 -08:00
|
|
|
const char *label;
|
2010-01-23 17:53:37 -08:00
|
|
|
Eina_Bool autorepeat;
|
|
|
|
Eina_Bool repeating;
|
|
|
|
double ar_threshold;
|
|
|
|
double ar_interval;
|
|
|
|
Ecore_Timer *timer;
|
2008-09-29 23:58:56 -07:00
|
|
|
};
|
|
|
|
|
2010-03-08 22:15:39 -08:00
|
|
|
static const char *widtype = NULL;
|
2008-10-06 18:23:49 -07:00
|
|
|
static void _del_hook(Evas_Object *obj);
|
2008-11-14 22:09:04 -08:00
|
|
|
static void _theme_hook(Evas_Object *obj);
|
2009-08-16 04:35:55 -07:00
|
|
|
static void _disable_hook(Evas_Object *obj);
|
2008-10-06 18:23:49 -07:00
|
|
|
static void _sizing_eval(Evas_Object *obj);
|
|
|
|
static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
|
2008-10-06 23:55:11 -07:00
|
|
|
static void _sub_del(void *data, Evas_Object *obj, void *event_info);
|
2008-10-06 18:23:49 -07:00
|
|
|
static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
|
2010-01-23 17:53:37 -08:00
|
|
|
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);
|
2010-01-10 22:23:00 -08:00
|
|
|
static void _on_focus_hook(void *data, Evas_Object *obj);
|
2010-09-22 10:45:43 -07:00
|
|
|
static void _activate(Evas_Object *obj);
|
|
|
|
static void _activate_hook(Evas_Object *obj);
|
2010-09-22 10:45:49 -07:00
|
|
|
static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
|
|
|
|
Evas_Callback_Type type, void *event_info);
|
2008-09-29 23:58:56 -07:00
|
|
|
|
Proxy Elementary widget signals to Edje.
Add support to automatic proxy events from Elementary to Edje using
callbacks described with Evas_Smart_Cb_Description and set to
Evas_Smart_Class or per-instance with
evas_object_smart_callbacks_descriptions_set().
Right now elm_widget is not subclassable, so there is no way to define
class signals, just instance signals.
Just doing it for button, lots of widgets to do... If you can help,
please follow the process:
* see example at src/lib/elm_button.c, copy it.
* read your widget documentation at Elementary.h
* grep for evas_object_smart_callback_call(), see if they are all
documented in Elementary.h, or if there are some missing. Fix Elementary.h
* paste and change based on fixed Elementary.h My recommendation is
to create "static const char []" variables and replace all
evas_object_smart_callback_call() with that, to force sync.
With callback descriptions pre-defined and using the same pointer with
a custom variation evas_object_smart_callback_call_ptr() we may later
optimize signal calling heavily, removing the requirement to call
eina_stringshare_add()/eina_stringshare_del() and also not mixing all
the callbacks in teh same list, instead having an array for defined
signals, and a list from there. These optimizations are not in, but
they are easily added later without breaking the API/ABI.
SVN revision: 47461
2010-03-25 17:58:14 -07:00
|
|
|
static const char SIG_CLICKED[] = "clicked";
|
|
|
|
static const char SIG_REPEATED[] = "repeated";
|
|
|
|
static const char SIG_UNPRESSED[] = "unpressed";
|
|
|
|
static const Evas_Smart_Cb_Description _signals[] = {
|
|
|
|
{SIG_CLICKED, ""},
|
|
|
|
{SIG_REPEATED, ""},
|
|
|
|
{SIG_UNPRESSED, ""},
|
|
|
|
{NULL, NULL}
|
|
|
|
};
|
|
|
|
|
2010-09-22 10:45:49 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
|
|
|
|
{
|
|
|
|
if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
|
|
|
|
Evas_Event_Key_Down *ev = event_info;
|
2010-09-22 10:45:53 -07:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return EINA_FALSE;
|
2010-09-22 10:45:49 -07:00
|
|
|
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
|
2010-09-29 05:22:41 -07:00
|
|
|
if (elm_widget_disabled_get(obj)) return EINA_FALSE;
|
2010-11-29 05:56:33 -08:00
|
|
|
if ((strcmp(ev->keyname, "Return")) &&
|
|
|
|
(strcmp(ev->keyname, "KP_Enter")) &&
|
|
|
|
(strcmp(ev->keyname, "space")))
|
2010-09-22 10:45:49 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
_activate(obj);
|
|
|
|
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
|
2010-09-22 10:45:53 -07:00
|
|
|
edje_object_signal_emit(wd->btn, "elm,anim,activate", "elm");
|
2010-09-22 10:45:49 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2008-09-29 23:58:56 -07:00
|
|
|
static void
|
2008-10-06 18:23:49 -07:00
|
|
|
_del_hook(Evas_Object *obj)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2008-10-06 18:23:49 -07:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-01-08 06:29:13 -08:00
|
|
|
if (!wd) return;
|
2008-11-14 22:09:04 -08:00
|
|
|
if (wd->label) eina_stringshare_del(wd->label);
|
2008-10-06 18:23:49 -07:00
|
|
|
free(wd);
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
2010-01-10 22:23:00 -08:00
|
|
|
static void
|
2010-03-09 09:51:30 -08:00
|
|
|
_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
|
2010-01-10 22:23:00 -08:00
|
|
|
{
|
2010-01-19 04:11:58 -08:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2010-03-08 23:30:48 -08:00
|
|
|
if (!wd) return;
|
2010-01-19 04:11:58 -08:00
|
|
|
if (elm_widget_focus_get(obj))
|
2010-04-20 13:03:05 -07:00
|
|
|
{
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,action,focus", "elm");
|
2010-09-18 19:30:14 -07:00
|
|
|
evas_object_focus_set(wd->btn, EINA_TRUE);
|
2010-04-20 13:03:05 -07:00
|
|
|
}
|
2010-01-19 04:11:58 -08:00
|
|
|
else
|
2010-04-20 13:03:05 -07:00
|
|
|
{
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm");
|
2010-09-18 19:30:14 -07:00
|
|
|
evas_object_focus_set(wd->btn, EINA_FALSE);
|
2010-04-20 13:03:05 -07:00
|
|
|
}
|
2010-01-10 22:23:00 -08:00
|
|
|
}
|
|
|
|
|
2008-11-14 22:09:04 -08:00
|
|
|
static void
|
|
|
|
_theme_hook(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2010-10-07 07:49:35 -07:00
|
|
|
const char *str;
|
2009-01-08 06:29:13 -08:00
|
|
|
if (!wd) return;
|
2010-05-11 18:03:46 -07:00
|
|
|
_elm_theme_object_set(obj, wd->btn, "button", "base", elm_widget_style_get(obj));
|
2008-12-08 01:24:46 -08:00
|
|
|
if (wd->icon)
|
|
|
|
edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
|
2008-11-15 05:58:50 -08:00
|
|
|
if (wd->label)
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
|
|
|
|
else
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
|
|
|
|
if (wd->icon)
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
|
|
|
|
else
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
|
|
|
|
edje_object_part_text_set(wd->btn, "elm.text", wd->label);
|
From: RAJEEV RANJAN <rajeev.r@samsung.com>
Subject: Patch to address some focus and disabling issue in elementary
widgets
We have observed some generic issues in Elementary widgets.
1. Widgets not getting disabled if we call elm_object_disabled_set(ob,
EINA_TRUE) followed by elm_object_style_set(obj, <style_name>);
This works fine if we disable the widget after changing the style(call
to theme_hook happens here).
It happens because we are not sending the edje signal in theme_hook of
the widgets, if the widget is already in disabled state.
I have added this code in theme_hook of elm_button as an example and
we will need to apply the similar stuff in all other widgets if needed.
2. The widget gets focused in a particular scenario even though we
call elm_object_focus_allow_set(obj, EINA_FALSE).
The code snippet to explain the scenario which we observed was like
this:
Evas_Object *button = NULL, *icon = NULL;
button = elm_button_add(parent);
elm_object_focus_allow_set(button, EINA_FALSE);
icon = elm_icon_add(button);
elm_icon_file_set(icon, EDJE_PATH, "test.icon");
elm_button_icon_set(button, icon);
An icon object does not take focus by default. But still whenever
the focus returned to the parent(layout in this case) after closing
some popup, the button gets focused though we had disabled it
explicitly.
The reason is in this case, when we call elm_icon_add(button), icon
gets added to button as a sub-object and in this call, we set
sd->child_can_focus for button(the parent) as true because till now,
the focus property for icon has not been set to false which by default
is true.
This was set later in the function elm_icon_add() as follows:
elm_widget_can_focus_set(obj, EINA_FALSE);
Actually this should be set before adding icon as sub-object of the
parent which in this case is a button.
I have done the required modification in the function elm_icon_add().
Attached to this mail is the patch file for these two issues.The
revision from which I have created this patch file is 53129.
We may need to do similar changes in other widgets if required.
SVN revision: 53137
2010-10-07 00:31:24 -07:00
|
|
|
if (elm_object_disabled_get(obj))
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
|
2010-10-07 00:44:50 -07:00
|
|
|
edje_object_message_signal_process(wd->btn);
|
|
|
|
edje_object_scale_set(wd->btn, elm_widget_scale_get(obj) * _elm_config->scale);
|
2010-10-07 07:49:35 -07:00
|
|
|
str = edje_object_data_get(wd->btn, "focus_highlight");
|
2010-10-22 14:41:22 -07:00
|
|
|
if ((str) && (!strcmp(str, "on")))
|
2010-10-07 07:49:35 -07:00
|
|
|
elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
|
|
|
|
else
|
|
|
|
elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
|
2008-11-14 22:09:04 -08:00
|
|
|
_sizing_eval(obj);
|
|
|
|
}
|
|
|
|
|
2009-08-16 04:35:55 -07:00
|
|
|
static void
|
|
|
|
_disable_hook(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2010-03-08 23:30:48 -08:00
|
|
|
if (!wd) return;
|
2009-08-16 04:35:55 -07:00
|
|
|
if (elm_widget_disabled_get(obj))
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
|
|
|
|
else
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
|
|
|
|
}
|
|
|
|
|
2010-10-07 07:49:35 -07:00
|
|
|
static void
|
|
|
|
_signal_emit_hook(Evas_Object *obj, const char *emission, const char *source)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return;
|
|
|
|
edje_object_signal_emit(wd->btn, emission, source);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_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)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return;
|
|
|
|
edje_object_signal_callback_add(wd->btn, emission, source, func_cb, data);
|
|
|
|
}
|
|
|
|
|
2010-10-29 11:21:58 -07:00
|
|
|
static void
|
|
|
|
_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)
|
2010-10-07 07:49:35 -07:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2010-10-29 11:21:58 -07:00
|
|
|
edje_object_signal_callback_del_full(wd->btn, emission, source, func_cb,
|
|
|
|
data);
|
2010-10-07 07:49:35 -07:00
|
|
|
}
|
|
|
|
|
2008-09-29 23:58:56 -07:00
|
|
|
static void
|
2008-10-06 18:23:49 -07:00
|
|
|
_sizing_eval(Evas_Object *obj)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2008-10-06 18:23:49 -07:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2009-09-26 10:39:29 -07:00
|
|
|
if (!wd) return;
|
2009-02-11 03:49:43 -08:00
|
|
|
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
|
|
|
|
edje_object_size_min_restricted_calc(wd->btn, &minw, &minh, minw, minh);
|
|
|
|
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
|
2008-10-06 18:23:49 -07:00
|
|
|
evas_object_size_hint_min_set(obj, minw, minh);
|
|
|
|
evas_object_size_hint_max_set(obj, maxw, maxh);
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-03-09 09:51:30 -08:00
|
|
|
_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2008-10-06 18:23:49 -07:00
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
2009-01-08 06:29:13 -08:00
|
|
|
if (!wd) return;
|
2008-10-06 23:55:11 -07:00
|
|
|
if (obj != wd->icon) return;
|
2008-10-06 18:23:49 -07:00
|
|
|
_sizing_eval(data);
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
2008-10-06 23:55:11 -07:00
|
|
|
static void
|
2010-03-09 09:51:30 -08:00
|
|
|
_sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
|
2008-10-06 23:55:11 -07:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Evas_Object *sub = event_info;
|
2009-09-26 10:39:29 -07:00
|
|
|
if (!wd) return;
|
2008-10-06 23:55:11 -07:00
|
|
|
if (sub == wd->icon)
|
|
|
|
{
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
|
2009-10-22 15:10:23 -07:00
|
|
|
evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
|
|
|
_changed_size_hints, obj);
|
2008-10-06 23:55:11 -07:00
|
|
|
wd->icon = NULL;
|
2009-07-06 23:46:51 -07:00
|
|
|
edje_object_message_signal_process(wd->btn);
|
2008-10-06 23:55:11 -07:00
|
|
|
_sizing_eval(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-09-29 23:58:56 -07:00
|
|
|
static void
|
2010-09-22 10:45:43 -07:00
|
|
|
_activate(Evas_Object *obj)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2010-09-22 10:45:43 -07:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-01-08 06:29:13 -08:00
|
|
|
if (!wd) return;
|
2010-04-08 08:15:22 -07:00
|
|
|
if (wd->timer)
|
|
|
|
{
|
|
|
|
ecore_timer_del(wd->timer);
|
|
|
|
wd->timer = NULL;
|
|
|
|
}
|
|
|
|
wd->repeating = EINA_FALSE;
|
2010-09-22 10:45:43 -07:00
|
|
|
evas_object_smart_callback_call(obj, SIG_CLICKED, NULL);
|
|
|
|
_signal_unpressed(obj, wd->btn, NULL, NULL); /* safe guard when the theme does not emit the 'unpress' signal */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_activate_hook(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
_activate(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_signal_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
|
|
|
|
{
|
|
|
|
_activate(data);
|
2010-01-23 17:53:37 -08:00
|
|
|
}
|
|
|
|
|
2010-06-25 02:58:14 -07:00
|
|
|
static Eina_Bool
|
2010-01-23 17:53:37 -08:00
|
|
|
_autorepeat_send(void *data)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
if (!wd) return ECORE_CALLBACK_CANCEL;
|
|
|
|
|
Proxy Elementary widget signals to Edje.
Add support to automatic proxy events from Elementary to Edje using
callbacks described with Evas_Smart_Cb_Description and set to
Evas_Smart_Class or per-instance with
evas_object_smart_callbacks_descriptions_set().
Right now elm_widget is not subclassable, so there is no way to define
class signals, just instance signals.
Just doing it for button, lots of widgets to do... If you can help,
please follow the process:
* see example at src/lib/elm_button.c, copy it.
* read your widget documentation at Elementary.h
* grep for evas_object_smart_callback_call(), see if they are all
documented in Elementary.h, or if there are some missing. Fix Elementary.h
* paste and change based on fixed Elementary.h My recommendation is
to create "static const char []" variables and replace all
evas_object_smart_callback_call() with that, to force sync.
With callback descriptions pre-defined and using the same pointer with
a custom variation evas_object_smart_callback_call_ptr() we may later
optimize signal calling heavily, removing the requirement to call
eina_stringshare_add()/eina_stringshare_del() and also not mixing all
the callbacks in teh same list, instead having an array for defined
signals, and a list from there. These optimizations are not in, but
they are easily added later without breaking the API/ABI.
SVN revision: 47461
2010-03-25 17:58:14 -07:00
|
|
|
evas_object_smart_callback_call(data, SIG_REPEATED, NULL);
|
2010-04-08 08:15:22 -07:00
|
|
|
if (!wd->repeating)
|
|
|
|
{
|
|
|
|
wd->timer = NULL;
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
2010-01-23 17:53:37 -08:00
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2010-06-25 02:58:14 -07:00
|
|
|
static Eina_Bool
|
2010-01-23 17:53:37 -08:00
|
|
|
_autorepeat_initial_send(void *data)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
if (!wd) return ECORE_CALLBACK_CANCEL;
|
|
|
|
|
2010-04-08 08:15:22 -07:00
|
|
|
if (wd->timer) ecore_timer_del(wd->timer);
|
|
|
|
wd->repeating = EINA_TRUE;
|
2010-01-23 17:53:37 -08:00
|
|
|
_autorepeat_send(data);
|
|
|
|
wd->timer = ecore_timer_add(wd->ar_interval, _autorepeat_send, data);
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2010-03-09 09:51:30 -08:00
|
|
|
_signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
|
2010-01-23 17:53:37 -08:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
if (!wd) return;
|
|
|
|
|
2010-10-22 14:41:22 -07:00
|
|
|
if ((wd->autorepeat) && (!wd->repeating))
|
2010-01-23 17:53:37 -08:00
|
|
|
{
|
|
|
|
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
|
2010-03-09 09:51:30 -08:00
|
|
|
_signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
|
2010-01-23 17:53:37 -08:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
if (!wd) return;
|
|
|
|
|
|
|
|
if (wd->timer)
|
|
|
|
{
|
|
|
|
ecore_timer_del(wd->timer);
|
|
|
|
wd->timer = NULL;
|
|
|
|
}
|
2010-04-08 08:15:22 -07:00
|
|
|
wd->repeating = EINA_FALSE;
|
|
|
|
evas_object_smart_callback_call(data, SIG_UNPRESSED, NULL);
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
2009-09-17 15:39:18 -07:00
|
|
|
/**
|
|
|
|
* Add a new button to the parent
|
|
|
|
* @param parent The parent object
|
|
|
|
* @return The new object or NULL if it cannot be created
|
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI Evas_Object *
|
|
|
|
elm_button_add(Evas_Object *parent)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2008-10-06 18:23:49 -07:00
|
|
|
Evas_Object *obj;
|
|
|
|
Evas *e;
|
|
|
|
Widget_Data *wd;
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2010-12-03 06:08:33 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
wd = ELM_NEW(Widget_Data);
|
|
|
|
e = evas_object_evas_get(parent);
|
|
|
|
obj = elm_widget_add(e);
|
2010-03-08 22:15:39 -08:00
|
|
|
ELM_SET_WIDTYPE(widtype, "button");
|
2009-05-13 05:21:52 -07:00
|
|
|
elm_widget_type_set(obj, "button");
|
|
|
|
elm_widget_sub_object_add(parent, obj);
|
2010-01-10 22:23:00 -08:00
|
|
|
elm_widget_on_focus_hook_set( obj, _on_focus_hook, NULL );
|
2008-10-06 18:23:49 -07:00
|
|
|
elm_widget_data_set(obj, wd);
|
|
|
|
elm_widget_del_hook_set(obj, _del_hook);
|
2008-11-14 22:09:04 -08:00
|
|
|
elm_widget_theme_hook_set(obj, _theme_hook);
|
2009-08-16 04:35:55 -07:00
|
|
|
elm_widget_disable_hook_set(obj, _disable_hook);
|
2010-10-07 07:49:35 -07:00
|
|
|
elm_widget_can_focus_set(obj, EINA_TRUE);
|
2010-09-22 10:45:43 -07:00
|
|
|
elm_widget_activate_hook_set(obj, _activate_hook);
|
2010-09-22 10:45:49 -07:00
|
|
|
elm_widget_event_hook_set(obj, _event_hook);
|
2010-10-07 07:49:35 -07:00
|
|
|
elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
|
|
|
|
elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
|
|
|
|
elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
wd->btn = edje_object_add(e);
|
2010-05-11 18:03:46 -07:00
|
|
|
_elm_theme_object_set(obj, wd->btn, "button", "base", "default");
|
2009-10-15 06:18:11 -07:00
|
|
|
edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
|
2009-09-26 10:39:29 -07:00
|
|
|
_signal_clicked, obj);
|
2010-01-23 17:53:37 -08:00
|
|
|
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);
|
2008-10-06 18:23:49 -07:00
|
|
|
elm_widget_resize_object_set(obj, wd->btn);
|
2008-10-06 23:55:11 -07:00
|
|
|
|
|
|
|
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2010-10-07 07:49:35 -07:00
|
|
|
_theme_hook(obj);
|
Proxy Elementary widget signals to Edje.
Add support to automatic proxy events from Elementary to Edje using
callbacks described with Evas_Smart_Cb_Description and set to
Evas_Smart_Class or per-instance with
evas_object_smart_callbacks_descriptions_set().
Right now elm_widget is not subclassable, so there is no way to define
class signals, just instance signals.
Just doing it for button, lots of widgets to do... If you can help,
please follow the process:
* see example at src/lib/elm_button.c, copy it.
* read your widget documentation at Elementary.h
* grep for evas_object_smart_callback_call(), see if they are all
documented in Elementary.h, or if there are some missing. Fix Elementary.h
* paste and change based on fixed Elementary.h My recommendation is
to create "static const char []" variables and replace all
evas_object_smart_callback_call() with that, to force sync.
With callback descriptions pre-defined and using the same pointer with
a custom variation evas_object_smart_callback_call_ptr() we may later
optimize signal calling heavily, removing the requirement to call
eina_stringshare_add()/eina_stringshare_del() and also not mixing all
the callbacks in teh same list, instead having an array for defined
signals, and a list from there. These optimizations are not in, but
they are easily added later without breaking the API/ABI.
SVN revision: 47461
2010-03-25 17:58:14 -07:00
|
|
|
|
|
|
|
// TODO: convert Elementary to subclassing of Evas_Smart_Class
|
|
|
|
// TODO: and save some bytes, making descriptions per-class and not instance!
|
|
|
|
evas_object_smart_callbacks_descriptions_set(obj, _signals);
|
2008-10-06 18:23:49 -07:00
|
|
|
return obj;
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
2009-09-17 15:39:18 -07:00
|
|
|
/**
|
|
|
|
* Set the label used in the button
|
|
|
|
*
|
|
|
|
* @param obj The button object
|
2009-10-15 06:18:11 -07:00
|
|
|
* @param label The text will be written on the button
|
2009-09-17 15:39:18 -07:00
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI void
|
|
|
|
elm_button_label_set(Evas_Object *obj, const char *label)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2010-03-08 22:15:39 -08:00
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype);
|
2008-10-06 18:23:49 -07:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-09-26 10:39:29 -07:00
|
|
|
if (!wd) return;
|
2010-03-13 13:01:26 -08:00
|
|
|
eina_stringshare_replace(&wd->label, label);
|
2008-10-06 18:23:49 -07:00
|
|
|
if (label)
|
2010-03-13 13:01:26 -08:00
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
|
2008-10-06 18:23:49 -07:00
|
|
|
else
|
2010-03-13 13:01:26 -08:00
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
|
2009-09-26 10:39:29 -07:00
|
|
|
edje_object_message_signal_process(wd->btn);
|
2008-10-06 18:23:49 -07:00
|
|
|
edje_object_part_text_set(wd->btn, "elm.text", label);
|
|
|
|
_sizing_eval(obj);
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
2010-03-08 23:30:48 -08:00
|
|
|
EAPI const char *
|
2010-03-23 20:06:00 -07:00
|
|
|
elm_button_label_get(const Evas_Object *obj)
|
2009-08-11 03:44:49 -07:00
|
|
|
{
|
2010-03-08 23:30:48 -08:00
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
|
2009-08-11 03:44:49 -07:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return NULL;
|
|
|
|
return wd->label;
|
|
|
|
}
|
|
|
|
|
2009-09-17 15:39:18 -07:00
|
|
|
/**
|
|
|
|
* Set the icon used for the button
|
|
|
|
*
|
2010-06-16 13:58:09 -07:00
|
|
|
* Once the icon object is set, a previously set one will be deleted
|
2010-10-14 11:54:42 -07:00
|
|
|
* If you want to keep that old content object, use the
|
|
|
|
* elm_button_icon_unset() function.
|
2010-06-16 13:58:09 -07:00
|
|
|
*
|
2009-09-17 15:39:18 -07:00
|
|
|
* @param obj The button object
|
2010-10-14 11:54:42 -07:00
|
|
|
* @param icon The icon object for the button
|
2009-09-17 15:39:18 -07:00
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI void
|
|
|
|
elm_button_icon_set(Evas_Object *obj, Evas_Object *icon)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2010-03-08 22:15:39 -08:00
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype);
|
2008-10-06 18:23:49 -07:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-01-08 06:29:13 -08:00
|
|
|
if (!wd) return;
|
2010-06-16 13:58:09 -07:00
|
|
|
if (wd->icon == icon) return;
|
|
|
|
if (wd->icon) evas_object_del(wd->icon);
|
|
|
|
wd->icon = icon;
|
|
|
|
if (icon)
|
2008-10-06 23:55:11 -07:00
|
|
|
{
|
2008-10-08 01:14:25 -07:00
|
|
|
elm_widget_sub_object_add(obj, icon);
|
2008-10-06 23:55:11 -07:00
|
|
|
evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
|
|
|
_changed_size_hints, obj);
|
2009-12-07 06:19:20 -08:00
|
|
|
edje_object_part_swallow(wd->btn, "elm.swallow.content", icon);
|
|
|
|
edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
|
2009-07-06 23:46:51 -07:00
|
|
|
edje_object_message_signal_process(wd->btn);
|
2008-10-06 23:55:11 -07:00
|
|
|
}
|
2010-06-16 13:58:09 -07:00
|
|
|
_sizing_eval(obj);
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
2008-12-08 01:24:46 -08:00
|
|
|
|
2010-03-08 23:30:48 -08:00
|
|
|
/**
|
|
|
|
* Get the icon used for the button
|
|
|
|
*
|
2010-10-14 11:54:42 -07:00
|
|
|
* Return the icon object which is set for this widget.
|
|
|
|
*
|
2010-03-08 23:30:48 -08:00
|
|
|
* @param obj The button object
|
2010-10-14 11:54:42 -07:00
|
|
|
* @return The icon object that is being used
|
2010-03-08 23:30:48 -08:00
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
2009-08-12 15:37:48 -07:00
|
|
|
EAPI Evas_Object *
|
2010-03-23 20:06:00 -07:00
|
|
|
elm_button_icon_get(const Evas_Object *obj)
|
2009-08-12 15:37:48 -07:00
|
|
|
{
|
2010-03-08 23:30:48 -08:00
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
|
2009-08-12 15:37:48 -07:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return NULL;
|
|
|
|
return wd->icon;
|
|
|
|
}
|
|
|
|
|
2010-10-14 11:54:42 -07:00
|
|
|
/**
|
|
|
|
* Unset the icon used for the button
|
|
|
|
*
|
|
|
|
* Unparent and return the icon object which was set for this widget.
|
|
|
|
*
|
|
|
|
* @param obj The button object
|
|
|
|
* @return The icon object that was being used
|
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
|
|
|
EAPI Evas_Object *
|
|
|
|
elm_button_icon_unset(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return NULL;
|
|
|
|
if (!wd->icon) return NULL;
|
|
|
|
Evas_Object *icon = wd->icon;
|
|
|
|
elm_widget_sub_object_del(obj, wd->icon);
|
|
|
|
edje_object_part_unswallow(wd->btn, wd->icon);
|
|
|
|
wd->icon = NULL;
|
|
|
|
return icon;
|
|
|
|
}
|
|
|
|
|
2010-01-23 17:53:37 -08:00
|
|
|
/**
|
|
|
|
* 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)
|
|
|
|
{
|
2010-03-08 22:15:39 -08:00
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype);
|
2010-01-23 17:53:37 -08:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return;
|
2010-03-08 23:30:48 -08:00
|
|
|
if (wd->timer)
|
|
|
|
{
|
|
|
|
ecore_timer_del(wd->timer);
|
|
|
|
wd->timer = NULL;
|
|
|
|
}
|
2010-01-23 17:53:37 -08:00
|
|
|
wd->autorepeat = on;
|
2010-04-08 08:15:22 -07:00
|
|
|
wd->repeating = EINA_FALSE;
|
2010-01-23 17:53:37 -08:00
|
|
|
}
|
|
|
|
|
2010-10-27 07:38:45 -07:00
|
|
|
/**
|
|
|
|
* Get if autorepeat event is on
|
|
|
|
*
|
|
|
|
* @param obj The button object
|
|
|
|
* @return If autorepeat is on
|
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
|
|
|
EAPI Eina_Bool
|
|
|
|
elm_button_autorepeat_get(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return EINA_FALSE;
|
|
|
|
return wd->autorepeat;
|
|
|
|
}
|
|
|
|
|
2010-01-23 17:53:37 -08:00
|
|
|
/**
|
|
|
|
* Set the initial timeout before the autorepeat event is generated
|
|
|
|
*
|
|
|
|
* @param obj The button object
|
|
|
|
* @param t Timeout
|
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
|
|
|
EAPI void
|
2010-03-14 15:33:52 -07:00
|
|
|
elm_button_autorepeat_initial_timeout_set(Evas_Object *obj, double t)
|
2010-01-23 17:53:37 -08:00
|
|
|
{
|
2010-03-08 22:15:39 -08:00
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype);
|
2010-01-23 17:53:37 -08:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return;
|
2010-03-08 23:30:48 -08:00
|
|
|
if (wd->ar_threshold == t) return;
|
2010-01-23 17:53:37 -08:00
|
|
|
if (wd->timer)
|
|
|
|
{
|
|
|
|
ecore_timer_del(wd->timer);
|
|
|
|
wd->timer = NULL;
|
|
|
|
}
|
|
|
|
wd->ar_threshold = t;
|
|
|
|
}
|
|
|
|
|
2010-10-27 07:38:45 -07:00
|
|
|
/**
|
|
|
|
* Get the initial timeout before the autorepeat event is generated
|
|
|
|
*
|
|
|
|
* @param obj The button object
|
|
|
|
* @return Timeout
|
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
|
|
|
EAPI double
|
|
|
|
elm_button_autorepeat_initial_timeout_get(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return 0.0;
|
|
|
|
return wd->ar_threshold;
|
|
|
|
}
|
|
|
|
|
2010-01-23 17:53:37 -08:00
|
|
|
/**
|
|
|
|
* Set the interval between each generated autorepeat event
|
|
|
|
*
|
|
|
|
* @param obj The button object
|
|
|
|
* @param t Interval
|
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
2010-10-27 07:38:45 -07:00
|
|
|
EAPI void
|
2010-01-23 17:53:37 -08:00
|
|
|
elm_button_autorepeat_gap_timeout_set(Evas_Object *obj, double t)
|
|
|
|
{
|
2010-03-08 22:15:39 -08:00
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype);
|
2010-01-23 17:53:37 -08:00
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return;
|
2010-03-08 23:30:48 -08:00
|
|
|
if (wd->ar_interval == t) return;
|
2010-04-08 08:15:22 -07:00
|
|
|
|
2010-01-23 17:53:37 -08:00
|
|
|
wd->ar_interval = t;
|
2010-10-22 14:41:22 -07:00
|
|
|
if ((wd->repeating) && (wd->timer)) ecore_timer_interval_set(wd->timer, t);
|
2010-01-23 17:53:37 -08:00
|
|
|
}
|
2010-10-27 07:38:45 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the interval between each generated autorepeat event
|
|
|
|
*
|
|
|
|
* @param obj The button object
|
|
|
|
* @return Interval
|
|
|
|
*
|
|
|
|
* @ingroup Button
|
|
|
|
*/
|
|
|
|
EAPI double
|
|
|
|
elm_button_autorepeat_gap_timeout_get(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
if (!wd) return 0.0;
|
|
|
|
return wd->ar_interval;
|
|
|
|
}
|