diff --git a/legacy/edje/src/lib/Edje.h b/legacy/edje/src/lib/Edje.h index 497e256645..c7c5207934 100644 --- a/legacy/edje/src/lib/Edje.h +++ b/legacy/edje/src/lib/Edje.h @@ -250,6 +250,8 @@ enum _Edje_External_Param_Type }; typedef enum _Edje_External_Param_Type Edje_External_Param_Type; +EAPI const char *edje_external_param_type_str(Edje_External_Param_Type type) EINA_PURE; + struct _Edje_External_Param { const char *name; @@ -325,7 +327,7 @@ typedef struct _Edje_External_Param_Info Edje_External_Param_Info; struct _Edje_External_Type { -#define EDJE_EXTERNAL_TYPE_ABI_VERSION (1) +#define EDJE_EXTERNAL_TYPE_ABI_VERSION (2) unsigned int abi_version; /**< always use: * - #EDJE_EXTERNAL_TYPE_ABI_VERSION to declare. * - edje_external_type_abi_version_get() to check. @@ -333,11 +335,13 @@ struct _Edje_External_Type const char *module; const char *module_name; - Evas_Object *(*add) (void *data, Evas *evas, Evas_Object *parent, const Eina_List *params); - void (*state_set) (void *data, Evas_Object *obj, const void *from_params, const void *to_params, float pos); - void (*signal_emit) (void *data, Evas_Object *obj, const char *emission, const char *source); - void *(*params_parse) (void *data, Evas_Object *obj, const Eina_List *params); - void (*params_free) (void *params); + Evas_Object *(*add) (void *data, Evas *evas, Evas_Object *parent, const Eina_List *params, const char *part_name); /**< creates the object to be used by Edje as the part */ + void (*state_set) (void *data, Evas_Object *obj, const void *from_params, const void *to_params, float pos); /**< called upon state changes, including the initial "default" 0.0 state. Parameters are the value returned by params_parse() */ + void (*signal_emit) (void *data, Evas_Object *obj, const char *emission, const char *source); /**< Feed a signal emitted with emission originally set as part_name:signal to this object (without the "part_name:" prefix) */ + Eina_Bool (*param_set) (void *data, Evas_Object *obj, const Edje_External_Param *param); /**< dynamically change a parameter of this external, called by scripts and user code. Returns @c EINA_TRUE on success */ + Eina_Bool (*param_get) (void *data, const Evas_Object *obj, Edje_External_Param *param); /**< dynamically fetch a parameter of this external, called by scripts and user code. Returns @c EINA_TRUE on success. (Must check parameter name and type!) */ + void *(*params_parse) (void *data, Evas_Object *obj, const Eina_List *params); /**< parses the list of parameters, converting into a friendly representation. Used with state_set() */ + void (*params_free) (void *params); /**< free parameters parsed with params_parse() */ /* The following callbacks aren't used by Edje itself, but by UI design tools instead */ @@ -345,6 +349,7 @@ struct _Edje_External_Type const char *(*description_get) (void *data); Evas_Object *(*icon_add) (void *data, Evas *e); Evas_Object *(*preview_add) (void *data, Evas *e); + const char *(*translate) (void *data, const char *orig); /**< called to translate parameters_info name properties for use in user interfaces that support internationalization (i18n) */ Edje_External_Param_Info *parameters_info; @@ -500,6 +505,11 @@ extern "C" { EAPI Eina_Bool edje_object_part_drag_page_get (const Evas_Object *obj, const char *part, double *dx, double *dy); EAPI Eina_Bool edje_object_part_drag_step (Evas_Object *obj, const char *part, double dx, double dy); EAPI Eina_Bool edje_object_part_drag_page (Evas_Object *obj, const char *part, double dx, double dy); + + EAPI Evas_Object *edje_object_part_external_object_get(const Evas_Object *obj, const char *part); + EAPI Eina_Bool edje_object_part_external_param_set(Evas_Object *obj, const char *part, const Edje_External_Param *param); + EAPI Eina_Bool edje_object_part_external_param_get(const Evas_Object *obj, const char *part, Edje_External_Param *param); + EAPI Eina_Bool edje_object_part_box_append (Evas_Object *obj, const char *part, Evas_Object *child); EAPI Eina_Bool edje_object_part_box_prepend (Evas_Object *obj, const char *part, Evas_Object *child); EAPI Eina_Bool edje_object_part_box_insert_before (Evas_Object *obj, const char *part, Evas_Object *child, const Evas_Object *reference); diff --git a/legacy/edje/src/lib/edje_edit.c b/legacy/edje/src/lib/edje_edit.c index 3ee8a97a57..854d4e6f8b 100644 --- a/legacy/edje/src/lib/edje_edit.c +++ b/legacy/edje/src/lib/edje_edit.c @@ -1782,7 +1782,7 @@ _edje_edit_real_part_add(Evas_Object *obj, const char *name, Edje_Part_Type type else if (ep->type == EDJE_PART_TYPE_GRADIENT) rp->object = evas_object_gradient_add(ed->evas); else - printf("EDJE ERROR: wrong part type %i!\n", ep->type); + ERR("wrong part type %i!", ep->type); if (rp->object) { evas_object_show(rp->object); @@ -1811,7 +1811,7 @@ _edje_edit_real_part_add(Evas_Object *obj, const char *name, Edje_Part_Type type if (ep->type == EDJE_PART_TYPE_EXTERNAL) { Evas_Object *child; - child = _edje_external_type_add(source, evas_object_evas_get(ed->obj), ed->obj, NULL); + child = _edje_external_type_add(source, evas_object_evas_get(ed->obj), ed->obj, NULL, name); if (child) _edje_real_part_swallow(rp, child); } @@ -2665,8 +2665,7 @@ edje_edit_state_add(Evas_Object *obj, const char *part, const char *name) p->s = eina_stringshare_add(pi->info.s.def); break; default: - printf("ERROR: unknown external parameter type '%d'\n", - p->type); + ERR("unknown external parameter type '%d'", p->type); } pd->external_params = eina_list_append(pd->external_params, p); pi++; @@ -3626,8 +3625,7 @@ edje_edit_state_external_param_get(Evas_Object *obj, const char *part, const cha *value = (void *)p->s; break; default: - printf("ERROR: unknown external parameter type '%d'\n", - p->type); + ERR("unknown external parameter type '%d'", p->type); } return EINA_TRUE; } @@ -3754,7 +3752,7 @@ edje_edit_state_external_param_set(Evas_Object *obj, const char *part, const cha p->s = eina_stringshare_add((const char *)va_arg(ap, char *)); break; default: - printf("ERROR: unknown external parameter type '%d'\n", type); + ERR("unknown external parameter type '%d'", type); } va_end(ap); diff --git a/legacy/edje/src/lib/edje_external.c b/legacy/edje/src/lib/edje_external.c index 019ef387fc..92ee40c3d9 100644 --- a/legacy/edje/src/lib/edje_external.c +++ b/legacy/edje/src/lib/edje_external.c @@ -7,6 +7,172 @@ static Eina_Hash *type_registry = NULL; static int init_count = 0; +/** + * @brief Converts type identifier to string nicer representation. + * + * This may be used to debug or other informational purposes. + * + * @param type the identifier to convert. + * @return the string with the string representation, or @c "(unknown)". + */ +EAPI const char * +edje_external_param_type_str(Edje_External_Param_Type type) +{ + switch (type) + { + case EDJE_EXTERNAL_PARAM_TYPE_INT: + return "INT"; + case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: + return "DOUBLE"; + case EDJE_EXTERNAL_PARAM_TYPE_STRING: + return "STRING"; + case EDJE_EXTERNAL_PARAM_TYPE_BOOL: + return "BOOL"; + default: + return "(unknown)"; + } +} + +/** + * @brief Get the object created by this external part. + * + * Parts of type external creates the part object using information + * provided by external plugins. It's somehow like "swallow" + * (edje_object_part_swallow()), but it's all set automatically. + * + * This function returns the part created by such external plugins and + * being currently managed by this Edje. + * + * @note Almost all swallow rules apply: you should not move, resize, + * hide, show, set the color or clipper of such part. It's a bit + * more restrictive as one must @b never delete this object! + * + * @param obj A valid Evas_Object handle + * @param part The part name + * @return The externally created object, or NULL if there is none or + * part is not an external. + */ +EAPI Evas_Object * +edje_object_part_external_object_get(const Evas_Object *obj, const char *part) +{ + Edje *ed; + Edje_Real_Part *rp; + + ed = _edje_fetch(obj); + if ((!ed) || (!part)) return NULL; + + /* Need to recalc before providing the object. */ + _edje_recalc_do(ed); + + rp = _edje_real_part_recursive_get(ed, (char *)part); + if (!rp) + { + ERR("no part '%s'", part); + return EINA_FALSE; + } + if (rp->part->type != EDJE_PART_TYPE_EXTERNAL) + { + ERR("cannot get external object of a part '%s' that is not EXTERNAL", + rp->part->name); + return NULL; + } + return rp->swallowed_object; +} + +/** + * @brief Set the parameter for the external part. + * + * Parts of type external may carry extra properties that have + * meanings defined by the external plugin. For instance, it may be a + * string that defines a button label and setting this property will + * change that label on the fly. + * + * @note external parts have parameters set when they change + * states. Those parameters will never be changed by this + * function. The interpretation of how state_set parameters and + * param_set will interact is up to the external plugin. + * + * @param obj A valid Evas_Object handle + * @param part The part name + * @param param the parameter details, including its name, type and + * actual value. This pointer should be valid, and the + * parameter must exist in + * #Edje_External_Type::parameters_info, with the exact type, + * otherwise the operation will fail and @c EINA_FALSE will be + * returned. + * + * @return @c EINA_TRUE if everything went fine, @c EINA_FALSE on errors. + */ +EAPI Eina_Bool +edje_object_part_external_param_set(Evas_Object *obj, const char *part, const Edje_External_Param *param) +{ + Edje *ed; + Edje_Real_Part *rp; + + if ((!param) || (!param->name)) return EINA_FALSE; + + ed = _edje_fetch(obj); + if ((!ed) || (!part)) return EINA_FALSE; + + rp = _edje_real_part_recursive_get(ed, (char *)part); + if (!rp) + { + ERR("no part '%s'", part); + return EINA_FALSE; + } + + return _edje_external_param_set(rp->swallowed_object, param); +} + +/** + * @brief Get the parameter for the external part. + * + * Parts of type external may carry extra properties that have + * meanings defined by the external plugin. For instance, it may be a + * string that defines a button label. This property can be modifed by + * state parameters, by explicit calls to + * edje_object_part_external_param_set() or getting the actual object + * with edje_object_part_external_object_get() and calling native + * functions. + * + * This function asks the external plugin what is the current value, + * independent on how it was set. + * + * @param obj A valid Evas_Object handle + * @param part The part name + + * @param param the parameter details. It is used as both input and + * output variable. This pointer should be valid, and the + * parameter must exist in + * #Edje_External_Type::parameters_info, with the exact type, + * otherwise the operation will fail and @c EINA_FALSE will be + * returned. + * + * @return @c EINA_TRUE if everything went fine and @p param members + * are filled with information, @c EINA_FALSE on errors and @p + * param member values are not set or valid. + */ +EAPI Eina_Bool +edje_object_part_external_param_get(const Evas_Object *obj, const char *part, Edje_External_Param *param) +{ + Edje *ed; + Edje_Real_Part *rp; + + if ((!param) || (!param->name)) return EINA_FALSE; + + ed = _edje_fetch(obj); + if ((!ed) || (!part)) return EINA_FALSE; + + rp = _edje_real_part_recursive_get(ed, (char *)part); + if (!rp) + { + ERR("no part '%s'", part); + return EINA_FALSE; + } + + return _edje_external_param_get(rp->swallowed_object, param); +} + /** * Register given type name to return the given information. * @@ -269,7 +435,7 @@ _edje_external_shutdown() } Evas_Object * -_edje_external_type_add(const char *type_name, Evas *evas, Evas_Object *parent, const Eina_List *params) +_edje_external_type_add(const char *type_name, Evas *evas, Evas_Object *parent, const Eina_List *params, const char *part_name) { Edje_External_Type *type; Evas_Object *obj; @@ -281,7 +447,7 @@ _edje_external_type_add(const char *type_name, Evas *evas, Evas_Object *parent, return NULL; } - obj = type->add(type->data, evas, parent, params); + obj = type->add(type->data, evas, parent, params, part_name); if (!obj) { ERR("External type '%s' returned NULL from constructor", type_name); @@ -308,6 +474,42 @@ _edje_external_signal_emit(Evas_Object *obj, const char *emission, const char *s type->signal_emit(type->data, obj, emission, source); } +Eina_Bool +_edje_external_param_set(Evas_Object *obj, const Edje_External_Param *param) +{ + Edje_External_Type *type = evas_object_data_get(obj, "Edje_External_Type"); + if (!type) + { + ERR("no external type for object %p", obj); + return EINA_FALSE; + } + if (!type->param_set) + { + ERR("external type '%s' from module '%s' does not provide param_set()", + type->module_name, type->module); + return EINA_FALSE; + } + return type->param_set(type->data, obj, param); +} + +Eina_Bool +_edje_external_param_get(const Evas_Object *obj, Edje_External_Param *param) +{ + Edje_External_Type *type = evas_object_data_get(obj, "Edje_External_Type"); + if (!type) + { + ERR("no external type for object %p", obj); + return EINA_FALSE; + } + if (!type->param_get) + { + ERR("external type '%s' from module '%s' does not provide param_set()", + type->module_name, type->module); + return EINA_FALSE; + } + return type->param_get(type->data, obj, param); +} + void _edje_external_params_free(Eina_List *external_params, Eina_Bool free_strings) { diff --git a/legacy/edje/src/lib/edje_load.c b/legacy/edje/src/lib/edje_load.c index 60897d8221..68a3eb0431 100644 --- a/legacy/edje/src/lib/edje_load.c +++ b/legacy/edje/src/lib/edje_load.c @@ -428,7 +428,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g rp->object = evas_object_table_add(ed->evas); break; default: - printf("EDJE ERROR: wrong part type %i!\n", ep->type); + ERR("wrong part type %i!", ep->type); break; } @@ -610,7 +610,7 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g case EDJE_PART_TYPE_EXTERNAL: { Evas_Object *child_obj; - child_obj = _edje_external_type_add(rp->part->source, evas_object_evas_get(ed->obj), ed->obj, rp->part->default_desc->external_params); + child_obj = _edje_external_type_add(rp->part->source, evas_object_evas_get(ed->obj), ed->obj, rp->part->default_desc->external_params, rp->part->name); if (child_obj) { _edje_real_part_swallow(rp, child_obj); diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 4c2aee86ca..4bdea783e5 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -1523,8 +1523,10 @@ const char *_edje_entry_cursor_content_get(Edje_Real_Part *rp, Edje_Cursor cur); void _edje_external_init(); void _edje_external_shutdown(); -Evas_Object *_edje_external_type_add(const char *type_name, Evas *evas, Evas_Object *parent, const Eina_List *params); +Evas_Object *_edje_external_type_add(const char *type_name, Evas *evas, Evas_Object *parent, const Eina_List *params, const char *part_name); void _edje_external_signal_emit(Evas_Object *obj, const char *emission, const char *source); +Eina_Bool _edje_external_param_set(Evas_Object *obj, const Edje_External_Param *param) EINA_ARG_NONNULL(1, 2); +Eina_Bool _edje_external_param_get(const Evas_Object *obj, Edje_External_Param *param) EINA_ARG_NONNULL(1, 2); void _edje_external_params_free(Eina_List *params, Eina_Bool free_strings); void _edje_external_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *params, Edje_Part_Description *chosen_desc); void *_edje_external_params_parse(Evas_Object *obj, const Eina_List *params);