forked from enlightenment/efl
343 lines
8.7 KiB
C
343 lines
8.7 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include "elementary_config.h"
|
|
#endif
|
|
|
|
#include "Elementary.h"
|
|
#include "private.h"
|
|
|
|
int _elm_ext_log_dom = -1;
|
|
|
|
static int init_count = 0;
|
|
|
|
void
|
|
external_elm_init(void)
|
|
{
|
|
int argc = 0;
|
|
char **argv = NULL;
|
|
|
|
init_count++;
|
|
DBG("elm_real_init\n");
|
|
if (init_count > 1) return;
|
|
ecore_app_args_get(&argc, &argv);
|
|
elm_init(argc, argv);
|
|
}
|
|
|
|
static void
|
|
external_elm_shutdown(void)
|
|
{
|
|
init_count--;
|
|
DBG("elm_real_shutdown\n");
|
|
if (init_count > 0) return;
|
|
elm_shutdown();
|
|
}
|
|
|
|
void
|
|
external_signal(void *data EINA_UNUSED, Evas_Object *obj, const char *sig,
|
|
const char *source)
|
|
{
|
|
char *_signal = strdup(sig);
|
|
char *p = _signal;
|
|
Evas_Object *content;
|
|
Edje_External_Type *type;
|
|
|
|
if (!p) goto on_error;
|
|
|
|
while ((*p!='\0') && (*p!=']'))
|
|
p++;
|
|
|
|
|
|
if ((*p=='\0') || (*(p+1)!=':'))
|
|
{
|
|
ERR("Invalid External Signal received: '%s' '%s'", sig, source);
|
|
goto on_error;
|
|
}
|
|
|
|
*p = '\0';
|
|
p+=2; //jump ']' and ':'
|
|
|
|
type = evas_object_data_get(obj, "Edje_External_Type");
|
|
if (!type)
|
|
{
|
|
ERR("no external type for object %p", obj);
|
|
goto on_error;
|
|
}
|
|
if (!type->content_get)
|
|
{
|
|
ERR("external type '%s' from module '%s' does not provide content_get()",
|
|
type->module_name, type->module);
|
|
goto on_error;
|
|
}
|
|
|
|
content = type->content_get(type->data, obj, _signal);
|
|
if (content)
|
|
edje_object_signal_emit(content, sig + (p - _signal), source);
|
|
|
|
on_error:
|
|
free(_signal);
|
|
return;
|
|
}
|
|
|
|
const char *
|
|
external_translate(void *data EINA_UNUSED, const char *orig)
|
|
{
|
|
// in future, mark all params as translatable and use dgettext()
|
|
// with "elementary" text domain here.
|
|
return orig;
|
|
}
|
|
|
|
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 EINA_UNUSED,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
void *event_info EINA_UNUSED)
|
|
{
|
|
Elm_External_Signals_Proxy_Context *ctxt = data;
|
|
external_elm_shutdown();
|
|
free(ctxt);
|
|
}
|
|
|
|
static void
|
|
_external_signal_proxy_cb(void *data, Evas_Object *obj EINA_UNUSED,
|
|
void *event_info EINA_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);
|
|
}
|
|
|
|
Eina_Bool
|
|
external_common_param_get(void *data EINA_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;
|
|
}
|
|
}
|
|
else if (!strcmp(param->name, "disabled"))
|
|
{
|
|
if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
|
|
{
|
|
param->i = elm_object_disabled_get(obj);
|
|
return EINA_TRUE;
|
|
}
|
|
}
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
Eina_Bool
|
|
external_common_param_set(void *data EINA_UNUSED, Evas_Object *obj,
|
|
const Edje_External_Param *param)
|
|
{
|
|
if (!strcmp(param->name, "style"))
|
|
{
|
|
if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING)
|
|
{
|
|
elm_object_style_set(obj, param->s);
|
|
return EINA_TRUE;
|
|
}
|
|
}
|
|
else if (!strcmp(param->name, "disabled"))
|
|
{
|
|
if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL)
|
|
{
|
|
elm_object_disabled_set(obj, param->i);
|
|
return EINA_TRUE;
|
|
}
|
|
}
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
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_FREE, _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);
|
|
}
|
|
}
|
|
|
|
void
|
|
external_common_params_parse(void *mem, void *data EINA_UNUSED,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const Eina_List *params)
|
|
{
|
|
Elm_Params *p;
|
|
const Eina_List *l;
|
|
Edje_External_Param *param;
|
|
|
|
p = mem;
|
|
EINA_LIST_FOREACH(params, l, param)
|
|
{
|
|
if (!strcmp(param->name, "style"))
|
|
p->style = eina_stringshare_add(param->s);
|
|
else if (!strcmp(param->name, "disabled"))
|
|
{
|
|
p->disabled = param->i;
|
|
p->disabled_exists = EINA_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
external_common_state_set(void *data EINA_UNUSED, Evas_Object *obj,
|
|
const void *from_params, const void *to_params,
|
|
float pos EINA_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);
|
|
if (p->disabled_exists)
|
|
elm_object_disabled_set(obj, p->disabled);
|
|
}
|
|
|
|
Evas_Object *
|
|
external_common_param_icon_get(Evas_Object *obj, const Edje_External_Param *p)
|
|
{
|
|
Evas_Object *edje, *parent_widget, *icon;
|
|
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;
|
|
icon = elm_icon_add(parent_widget);
|
|
|
|
if ((edje_file_group_exists(file, p->s)) &&
|
|
(elm_image_file_set(icon, file, p->s)))
|
|
return icon;
|
|
if (elm_icon_standard_set(icon, p->s))
|
|
return icon;
|
|
|
|
ERR("Failed to set icon: '%s'", p->s);
|
|
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);
|
|
}
|
|
|
|
Evas_Object *
|
|
external_common_param_elm_layout_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)
|
|
{
|
|
ret = elm_layout_add(parent_widget);
|
|
if (elm_layout_file_set(ret, file, p->s))
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
ret = edje_object_add(evas_object_evas_get(edje));
|
|
if (edje_object_file_set(ret, file, p->s))
|
|
return ret;
|
|
}
|
|
evas_object_del(ret);
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
external_common_params_free(void *params)
|
|
{
|
|
Elm_Params *p = params;
|
|
if (p->style)
|
|
eina_stringshare_del(p->style);
|
|
}
|
|
|
|
#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)
|
|
{
|
|
_elm_ext_log_dom = eina_log_domain_register("elm-externals",
|
|
EINA_COLOR_LIGHTBLUE);
|
|
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);
|
|
if (_elm_ext_log_dom >= 0) eina_log_domain_unregister(_elm_ext_log_dom);
|
|
_elm_ext_log_dom = -1;
|
|
}
|
|
|
|
EINA_MODULE_INIT(elm_mod_init);
|
|
EINA_MODULE_SHUTDOWN(elm_mod_shutdown);
|