Port to new Edje EXTERNAL API goodies!
Now it is possible to change labels and lots of other parameters
directly through Edje's API.
BIG FAT NOTE: this is a convenience that comes with a reasonable
price. If you have hot paths, like loops, then avoid calling this
and use the object directly. This functions add a cost to check
edje, then find the part, then get the type, then get the
param_set/param_get methods, then calling it, then finding the
parameters using strcmp(), then checking the type and just then it
will call the actual method. So whenever possible, just call the
method directly.
Due the reasoning of the "big fat note" I'm adding this inside edje
externals only. The code would be almost the same to expose it in
Elementary.h as elm_widget_property_set/get, but then I know people
would misuse it... actually this kind of stuff could be easily ported
to Evas smart object, but then abuse and slowness will hunt us
foreveeeeer...
SVN revision: 47457
2010-03-25 11:10:25 -07:00
|
|
|
#include "Elementary.h"
|
2009-12-05 17:22:54 -08:00
|
|
|
#include "private.h"
|
|
|
|
|
2010-03-25 22:20:30 -07:00
|
|
|
int _elm_log_dom = -1;
|
|
|
|
|
2009-12-05 17:22:54 -08:00
|
|
|
void
|
2010-08-01 10:29:20 -07:00
|
|
|
external_signal(void *data __UNUSED__, Evas_Object *obj, const char *signal, const char *source)
|
2009-12-05 17:22:54 -08:00
|
|
|
{
|
2010-08-01 10:29:20 -07:00
|
|
|
char *_signal = strdup(signal);
|
|
|
|
char *p = _signal;
|
|
|
|
Evas_Object *content;
|
|
|
|
|
|
|
|
while((*p!='\0') && (*p!=']'))
|
|
|
|
p++;
|
|
|
|
|
|
|
|
|
|
|
|
if((*p=='\0') || (*(p+1)!=':'))
|
|
|
|
{
|
|
|
|
ERR("Invalid External Signal received: '%s' '%s'\n", signal, source);
|
|
|
|
free(_signal);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = '\0';
|
|
|
|
p+=2; //jump ']' and ':'
|
|
|
|
|
|
|
|
Edje_External_Type *type = evas_object_data_get(obj, "Edje_External_Type");
|
|
|
|
if (!type->content_get)
|
|
|
|
{
|
|
|
|
ERR("external type '%s' from module '%s' does not provide content_get()",
|
|
|
|
type->module_name, type->module);
|
|
|
|
free(_signal);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
|
|
|
content = type->content_get(type->data, obj, _signal);
|
|
|
|
free(_signal);
|
|
|
|
if(content)
|
|
|
|
edje_object_signal_emit(content, signal + (p - _signal), source);
|
2009-12-05 17:22:54 -08:00
|
|
|
}
|
|
|
|
|
Port to new Edje EXTERNAL API goodies!
Now it is possible to change labels and lots of other parameters
directly through Edje's API.
BIG FAT NOTE: this is a convenience that comes with a reasonable
price. If you have hot paths, like loops, then avoid calling this
and use the object directly. This functions add a cost to check
edje, then find the part, then get the type, then get the
param_set/param_get methods, then calling it, then finding the
parameters using strcmp(), then checking the type and just then it
will call the actual method. So whenever possible, just call the
method directly.
Due the reasoning of the "big fat note" I'm adding this inside edje
externals only. The code would be almost the same to expose it in
Elementary.h as elm_widget_property_set/get, but then I know people
would misuse it... actually this kind of stuff could be easily ported
to Evas smart object, but then abuse and slowness will hunt us
foreveeeeer...
SVN revision: 47457
2010-03-25 11:10:25 -07:00
|
|
|
const char *
|
|
|
|
external_translate(void *data __UNUSED__, const char *orig)
|
|
|
|
{
|
|
|
|
// in future, mark all params as translatable and use dgettext()
|
|
|
|
// with "elementary" text domain here.
|
|
|
|
return orig;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
typedef struct {
|
|
|
|
const char *emission;
|
|
|
|
const char *source;
|
|
|
|
Evas_Object *edje;
|
|
|
|
} Elm_External_Signals_Proxy_Context;
|
|
|
|
|
|
|
|
static void
|
|
|
|
_external_signal_proxy_free_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
|
|
|
{
|
|
|
|
Elm_External_Signals_Proxy_Context *ctxt = data;
|
|
|
|
free(ctxt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_external_signal_proxy_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
|
|
|
{
|
|
|
|
Elm_External_Signals_Proxy_Context *ctxt = data;
|
|
|
|
// TODO: Is it worth to check Evas_Smart_Cb_Description and do something
|
|
|
|
// TODO: with event_info given its description?
|
|
|
|
edje_object_signal_emit(ctxt->edje, ctxt->emission, ctxt->source);
|
|
|
|
}
|
|
|
|
|
2010-10-21 15:03:43 -07:00
|
|
|
Eina_Bool
|
|
|
|
external_common_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param)
|
|
|
|
{
|
|
|
|
if (!strcmp(param->name, "style"))
|
|
|
|
{
|
|
|
|
if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
|
|
|
|
{
|
|
|
|
param->s = elm_object_style_get(obj);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_Bool
|
2010-10-22 05:05:45 -07:00
|
|
|
external_common_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param)
|
2010-10-21 15:03:43 -07:00
|
|
|
{
|
|
|
|
if (!strcmp(param->name, "style"))
|
|
|
|
{
|
|
|
|
if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
|
|
|
|
{
|
|
|
|
elm_object_style_set(obj, param->s);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
void
|
|
|
|
external_signals_proxy(Evas_Object *obj, Evas_Object *edje, const char *part_name)
|
|
|
|
{
|
|
|
|
const Evas_Smart_Cb_Description **cls_descs, **inst_descs;
|
|
|
|
unsigned int cls_count, inst_count, total;
|
|
|
|
Elm_External_Signals_Proxy_Context *ctxt;
|
|
|
|
|
|
|
|
evas_object_smart_callbacks_descriptions_get
|
|
|
|
(obj, &cls_descs, &cls_count, &inst_descs, &inst_count);
|
|
|
|
|
|
|
|
total = cls_count + inst_count;
|
|
|
|
if (!total) return;
|
|
|
|
ctxt = malloc(sizeof(Elm_External_Signals_Proxy_Context) * total);
|
|
|
|
if (!ctxt) return;
|
|
|
|
evas_object_event_callback_add
|
|
|
|
(obj, EVAS_CALLBACK_DEL, _external_signal_proxy_free_cb, ctxt);
|
|
|
|
|
|
|
|
for (; cls_count > 0; cls_count--, cls_descs++, ctxt++)
|
|
|
|
{
|
|
|
|
const Evas_Smart_Cb_Description *d = *cls_descs;
|
|
|
|
ctxt->emission = d->name;
|
|
|
|
ctxt->source = part_name;
|
|
|
|
ctxt->edje = edje;
|
|
|
|
evas_object_smart_callback_add
|
|
|
|
(obj, d->name, _external_signal_proxy_cb, ctxt);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; inst_count > 0; inst_count--, inst_descs++, ctxt++)
|
|
|
|
{
|
|
|
|
const Evas_Smart_Cb_Description *d = *inst_descs;
|
|
|
|
ctxt->emission = d->name;
|
|
|
|
ctxt->source = part_name;
|
|
|
|
ctxt->edje = edje;
|
|
|
|
evas_object_smart_callback_add
|
|
|
|
(obj, d->name, _external_signal_proxy_cb, ctxt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-21 15:03:43 -07:00
|
|
|
void
|
|
|
|
external_common_params_parse(void *mem, void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params)
|
2009-12-05 17:22:54 -08:00
|
|
|
{
|
|
|
|
Elm_Params *p;
|
|
|
|
const Eina_List *l;
|
|
|
|
Edje_External_Param *param;
|
|
|
|
|
2010-10-21 15:03:43 -07:00
|
|
|
p = mem;
|
2009-12-05 17:22:54 -08:00
|
|
|
EINA_LIST_FOREACH(params, l, param)
|
|
|
|
{
|
2010-10-21 15:03:43 -07:00
|
|
|
if (!strcmp(param->name, "style"))
|
|
|
|
{
|
|
|
|
p->style = eina_stringshare_add(param->s);
|
|
|
|
break;
|
|
|
|
}
|
2009-12-05 17:22:54 -08:00
|
|
|
}
|
2010-10-21 15:03:43 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
external_common_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__)
|
|
|
|
{
|
|
|
|
const Elm_Params *p;
|
|
|
|
if (to_params) p = to_params;
|
|
|
|
else if (from_params) p = from_params;
|
|
|
|
else return;
|
|
|
|
|
|
|
|
if (p->style)
|
|
|
|
elm_object_style_set(obj, p->style);
|
2009-12-05 17:22:54 -08:00
|
|
|
}
|
|
|
|
|
Port to new Edje EXTERNAL API goodies!
Now it is possible to change labels and lots of other parameters
directly through Edje's API.
BIG FAT NOTE: this is a convenience that comes with a reasonable
price. If you have hot paths, like loops, then avoid calling this
and use the object directly. This functions add a cost to check
edje, then find the part, then get the type, then get the
param_set/param_get methods, then calling it, then finding the
parameters using strcmp(), then checking the type and just then it
will call the actual method. So whenever possible, just call the
method directly.
Due the reasoning of the "big fat note" I'm adding this inside edje
externals only. The code would be almost the same to expose it in
Elementary.h as elm_widget_property_set/get, but then I know people
would misuse it... actually this kind of stuff could be easily ported
to Evas smart object, but then abuse and slowness will hunt us
foreveeeeer...
SVN revision: 47457
2010-03-25 11:10:25 -07:00
|
|
|
Evas_Object *
|
|
|
|
external_common_param_icon_get(Evas_Object *obj, const Edje_External_Param *p)
|
2009-12-05 17:22:54 -08:00
|
|
|
{
|
Port to new Edje EXTERNAL API goodies!
Now it is possible to change labels and lots of other parameters
directly through Edje's API.
BIG FAT NOTE: this is a convenience that comes with a reasonable
price. If you have hot paths, like loops, then avoid calling this
and use the object directly. This functions add a cost to check
edje, then find the part, then get the type, then get the
param_set/param_get methods, then calling it, then finding the
parameters using strcmp(), then checking the type and just then it
will call the actual method. So whenever possible, just call the
method directly.
Due the reasoning of the "big fat note" I'm adding this inside edje
externals only. The code would be almost the same to expose it in
Elementary.h as elm_widget_property_set/get, but then I know people
would misuse it... actually this kind of stuff could be easily ported
to Evas smart object, but then abuse and slowness will hunt us
foreveeeeer...
SVN revision: 47457
2010-03-25 11:10:25 -07:00
|
|
|
Evas_Object *edje, *parent_widget, *icon;
|
|
|
|
const char *file;
|
2009-12-05 17:22:54 -08:00
|
|
|
|
Port to new Edje EXTERNAL API goodies!
Now it is possible to change labels and lots of other parameters
directly through Edje's API.
BIG FAT NOTE: this is a convenience that comes with a reasonable
price. If you have hot paths, like loops, then avoid calling this
and use the object directly. This functions add a cost to check
edje, then find the part, then get the type, then get the
param_set/param_get methods, then calling it, then finding the
parameters using strcmp(), then checking the type and just then it
will call the actual method. So whenever possible, just call the
method directly.
Due the reasoning of the "big fat note" I'm adding this inside edje
externals only. The code would be almost the same to expose it in
Elementary.h as elm_widget_property_set/get, but then I know people
would misuse it... actually this kind of stuff could be easily ported
to Evas smart object, but then abuse and slowness will hunt us
foreveeeeer...
SVN revision: 47457
2010-03-25 11:10:25 -07:00
|
|
|
if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
|
|
|
|
return NULL;
|
2009-12-05 17:22:54 -08:00
|
|
|
|
Port to new Edje EXTERNAL API goodies!
Now it is possible to change labels and lots of other parameters
directly through Edje's API.
BIG FAT NOTE: this is a convenience that comes with a reasonable
price. If you have hot paths, like loops, then avoid calling this
and use the object directly. This functions add a cost to check
edje, then find the part, then get the type, then get the
param_set/param_get methods, then calling it, then finding the
parameters using strcmp(), then checking the type and just then it
will call the actual method. So whenever possible, just call the
method directly.
Due the reasoning of the "big fat note" I'm adding this inside edje
externals only. The code would be almost the same to expose it in
Elementary.h as elm_widget_property_set/get, but then I know people
would misuse it... actually this kind of stuff could be easily ported
to Evas smart object, but then abuse and slowness will hunt us
foreveeeeer...
SVN revision: 47457
2010-03-25 11:10:25 -07:00
|
|
|
edje = evas_object_smart_parent_get(obj);
|
|
|
|
edje_object_file_get(edje, &file, NULL);
|
2009-12-19 16:28:02 -08:00
|
|
|
|
Port to new Edje EXTERNAL API goodies!
Now it is possible to change labels and lots of other parameters
directly through Edje's API.
BIG FAT NOTE: this is a convenience that comes with a reasonable
price. If you have hot paths, like loops, then avoid calling this
and use the object directly. This functions add a cost to check
edje, then find the part, then get the type, then get the
param_set/param_get methods, then calling it, then finding the
parameters using strcmp(), then checking the type and just then it
will call the actual method. So whenever possible, just call the
method directly.
Due the reasoning of the "big fat note" I'm adding this inside edje
externals only. The code would be almost the same to expose it in
Elementary.h as elm_widget_property_set/get, but then I know people
would misuse it... actually this kind of stuff could be easily ported
to Evas smart object, but then abuse and slowness will hunt us
foreveeeeer...
SVN revision: 47457
2010-03-25 11:10:25 -07:00
|
|
|
parent_widget = elm_widget_parent_widget_get(obj);
|
2010-03-25 22:44:30 -07:00
|
|
|
if (!parent_widget)
|
|
|
|
parent_widget = edje;
|
|
|
|
icon = elm_icon_add(parent_widget);
|
Port to new Edje EXTERNAL API goodies!
Now it is possible to change labels and lots of other parameters
directly through Edje's API.
BIG FAT NOTE: this is a convenience that comes with a reasonable
price. If you have hot paths, like loops, then avoid calling this
and use the object directly. This functions add a cost to check
edje, then find the part, then get the type, then get the
param_set/param_get methods, then calling it, then finding the
parameters using strcmp(), then checking the type and just then it
will call the actual method. So whenever possible, just call the
method directly.
Due the reasoning of the "big fat note" I'm adding this inside edje
externals only. The code would be almost the same to expose it in
Elementary.h as elm_widget_property_set/get, but then I know people
would misuse it... actually this kind of stuff could be easily ported
to Evas smart object, but then abuse and slowness will hunt us
foreveeeeer...
SVN revision: 47457
2010-03-25 11:10:25 -07:00
|
|
|
|
|
|
|
if (elm_icon_file_set(icon, file, p->s))
|
|
|
|
return icon;
|
|
|
|
if (elm_icon_standard_set(icon, p->s))
|
|
|
|
return icon;
|
|
|
|
|
|
|
|
evas_object_del(icon);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
external_common_icon_param_parse(Evas_Object **icon, Evas_Object *obj, const Eina_List *params)
|
|
|
|
{
|
|
|
|
Edje_External_Param *p = edje_external_param_find(params, "icon");
|
|
|
|
*icon = external_common_param_icon_get(obj, p);
|
2009-12-05 17:22:54 -08:00
|
|
|
}
|
|
|
|
|
2010-03-29 10:19:35 -07:00
|
|
|
Evas_Object *
|
|
|
|
external_common_param_edje_object_get(Evas_Object *obj, const Edje_External_Param *p)
|
|
|
|
{
|
|
|
|
Evas_Object *edje, *parent_widget, *ret;
|
|
|
|
const char *file;
|
|
|
|
|
|
|
|
if ((!p) || (!p->s) || (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
edje = evas_object_smart_parent_get(obj);
|
|
|
|
edje_object_file_get(edje, &file, NULL);
|
|
|
|
|
|
|
|
parent_widget = elm_widget_parent_widget_get(obj);
|
|
|
|
if (!parent_widget)
|
|
|
|
parent_widget = edje;
|
|
|
|
|
|
|
|
ret = edje_object_add(evas_object_evas_get(parent_widget));
|
|
|
|
|
|
|
|
if (edje_object_file_set(ret, file, p->s))
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
evas_object_del(ret);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-12-05 17:22:54 -08:00
|
|
|
void
|
|
|
|
external_common_params_free(void *params)
|
|
|
|
{
|
|
|
|
Elm_Params *p = params;
|
2010-10-21 15:03:43 -07:00
|
|
|
if (p->style)
|
|
|
|
eina_stringshare_del(p->style);
|
|
|
|
}
|
2009-12-05 17:22:54 -08:00
|
|
|
|
|
|
|
#define DEFINE_TYPE(type_name) \
|
|
|
|
extern const Edje_External_Type external_##type_name##_type;
|
|
|
|
#include "modules.inc"
|
|
|
|
#undef DEFINE_TYPE
|
|
|
|
|
|
|
|
static Edje_External_Type_Info elm_external_types[] =
|
|
|
|
{
|
|
|
|
#define DEFINE_TYPE(type_name) \
|
|
|
|
{"elm/"#type_name, &external_##type_name##_type},
|
|
|
|
#include "modules.inc"
|
|
|
|
#undef DEFINE_TYPE
|
|
|
|
{NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
elm_mod_init(void)
|
|
|
|
{
|
2010-03-26 18:24:40 -07:00
|
|
|
int argc = 0;
|
|
|
|
char **argv = NULL;
|
|
|
|
|
|
|
|
ecore_app_args_get(&argc, &argv);
|
|
|
|
elm_init(argc, argv);
|
|
|
|
|
2010-03-25 22:20:30 -07:00
|
|
|
_elm_log_dom = eina_log_domain_register("elm-externals", EINA_COLOR_LIGHTBLUE);
|
2009-12-05 17:22:54 -08:00
|
|
|
edje_external_type_array_register(elm_external_types);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
elm_mod_shutdown(void)
|
|
|
|
{
|
|
|
|
edje_external_type_array_unregister(elm_external_types);
|
2010-03-31 05:06:12 -07:00
|
|
|
|
|
|
|
eina_log_domain_unregister(_elm_log_dom);
|
|
|
|
_elm_log_dom = -1;
|
|
|
|
|
|
|
|
elm_shutdown();
|
2009-12-05 17:22:54 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
EINA_MODULE_INIT(elm_mod_init);
|
|
|
|
EINA_MODULE_SHUTDOWN(elm_mod_shutdown);
|