Edje EXTERNAL API break, for good.

I'm now introducing a couple of goodies to make externals more useful,
they are:

 * add: extra parameter with the part name. This may be used by
   external objects to emit signals in the name of that part.

 * param_set/param_get: set parameters at runtime, given their names
   and types. This avoids requiring users to get the actual object and
   call methods. This abstraction is also good because it let one uses
   Elementary without even linking to it ;-) (this have limits, like
   complex types are not supported).  Right now this is just exposed
   to C, but goal is to have it exposed in Embryo and Lua as well.

 * translate: new method to translate previously strings that are
   specified statically, such as the parameters names.


Four new functions got added to the Edje API:

 * edje_object_part_external_object_get() so we don't have to abuse
   edje_object_part_swallow_get()

 * edje_object_part_external_param_set() and
   edje_object_part_external_param_get() that call the external type's
   functions.

 * edje_external_param_type_str() to convert types to string and
   provide nicer debugs :-)


TODO:
  * expose external_param_set()/external_param_get() to Embryo and Lua.




SVN revision: 47456
This commit is contained in:
Gustavo Sverzut Barbieri 2010-03-25 18:05:42 +00:00
parent 49da44bf6f
commit cfecbc912b
5 changed files with 230 additions and 18 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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);