From 257cb6f05f0c28865ad0c38141ad5b835f30a628 Mon Sep 17 00:00:00 2001 From: barbieri Date: Mon, 29 Mar 2010 21:51:40 +0000 Subject: [PATCH] Add CHOICES to EXTERNAL support. Choices are useful to represent enumerations and restricted set of elements to user. Usually this is displayed in hoversel/comboboxes. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/edje@47570 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- data/include/edje.inc | 3 + src/bin/edje_cc_handlers.c | 42 +++++++++ src/lib/Edje.h | 29 +++++- src/lib/edje_edit.c | 45 +++++++++- src/lib/edje_embryo.c | 104 +++++++++++++++++++++ src/lib/edje_external.c | 25 ++++++ src/lib/edje_program.c | 219 ++++++++++++++++++++++++++++++++++++--------- 7 files changed, 422 insertions(+), 45 deletions(-) diff --git a/data/include/edje.inc b/data/include/edje.inc index 49097d9..8faceec 100644 --- a/data/include/edje.inc +++ b/data/include/edje.inc @@ -158,6 +158,9 @@ native external_param_set_float(id, param_name[], Float:value); native external_param_get_strlen(id, param_name[]); native external_param_get_str(id, param_name[], value[], value_maxlen); native external_param_set_str(id, param_name[], value[]); +native external_param_get_choice_strlen(id, param_name[]); +native external_param_get_choice(id, param_name[], value[], value_maxlen); +native external_param_set_choice(id, param_name[], value[]); native external_param_get_bool(id, param_name[]); native external_param_set_bool(id, param_name[], value); diff --git a/src/bin/edje_cc_handlers.c b/src/bin/edje_cc_handlers.c index ca808a1..8318bd4 100644 --- a/src/bin/edje_cc_handlers.c +++ b/src/bin/edje_cc_handlers.c @@ -240,6 +240,8 @@ static void st_collections_group_parts_part_description_params_double(void); static void st_collections_group_programs_program_name(void); static void st_collections_group_parts_part_description_params_string(void); +static void st_collections_group_parts_part_description_params_bool(void); +static void st_collections_group_parts_part_description_params_choice(void); static void st_collections_group_programs_program_signal(void); static void st_collections_group_programs_program_source(void); static void st_collections_group_programs_program_filter(void); @@ -460,6 +462,8 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.description.params.int", st_collections_group_parts_part_description_params_int}, {"collections.group.parts.part.description.params.double", st_collections_group_parts_part_description_params_double}, {"collections.group.parts.part.description.params.string", st_collections_group_parts_part_description_params_string}, + {"collections.group.parts.part.description.params.bool", st_collections_group_parts_part_description_params_bool}, + {"collections.group.parts.part.description.params.choice", st_collections_group_parts_part_description_params_choice}, {"collections.group.parts.part.description.images.image", st_images_image}, /* dup */ {"collections.group.parts.part.description.font", st_fonts_font}, /* dup */ {"collections.group.parts.part.description.fonts.font", st_fonts_font}, /* dup */ @@ -6204,6 +6208,8 @@ st_collections_group_parts_part_description_perspective_focal(void) int: "name" 0; double: "other_name" 0.0; string: "another_name" "some text"; + bool: "name" 1; + choice: "some_name" "value"; } .. } @@ -6264,12 +6270,14 @@ _st_collections_group_parts_part_description_params(Edje_External_Param_Type typ switch (type) { + case EDJE_EXTERNAL_PARAM_TYPE_BOOL: case EDJE_EXTERNAL_PARAM_TYPE_INT: param->i = parse_int(1); break; case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: param->d = parse_float(1); break; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: case EDJE_EXTERNAL_PARAM_TYPE_STRING: param->s = parse_str(1); break; @@ -6327,6 +6335,40 @@ st_collections_group_parts_part_description_params_string(void) _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_STRING); } +/** + @page edcref + @property + bool + @parameters + [param_name] [bool_value] + @effect + Adds an boolean parameter for an external object. Value must be 0 or 1. + @endproperty +*/ +static void +st_collections_group_parts_part_description_params_bool(void) +{ + _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_BOOL); +} + +/** + @page edcref + @property + choice + @parameters + [param_name] [choice_string] + @effect + Adds a choice parameter for an external object. The possible + choice values are defined by external type at their register time + and will be validated at runtime. + @endproperty +*/ +static void +st_collections_group_parts_part_description_params_choice(void) +{ + _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_CHOICE); +} + /** @edcsection{program, Program block} diff --git a/src/lib/Edje.h b/src/lib/Edje.h index 9f8a1cd..3d1b8b1 100644 --- a/src/lib/Edje.h +++ b/src/lib/Edje.h @@ -247,6 +247,7 @@ enum _Edje_External_Param_Type EDJE_EXTERNAL_PARAM_TYPE_DOUBLE, EDJE_EXTERNAL_PARAM_TYPE_STRING, EDJE_EXTERNAL_PARAM_TYPE_BOOL, + EDJE_EXTERNAL_PARAM_TYPE_CHOICE, EDJE_EXTERNAL_PARAM_TYPE_MAX }; typedef enum _Edje_External_Param_Type Edje_External_Param_Type; @@ -258,9 +259,9 @@ struct _Edje_External_Param const char *name; Edje_External_Param_Type type; // XXX these could be in a union, but eet doesn't support them (or does it?) - int i; + int i; /**< used by both integer and boolean */ double d; - const char *s; + const char *s; /**< used by both string and choice */ }; typedef struct _Edje_External_Param Edje_External_Param; @@ -293,6 +294,11 @@ struct _Edje_External_Param_Info const char *false_str; const char *true_str; } b; + struct + { + const char *def; + const char **choices; /* NULL terminated array */ + } c; } info; }; typedef struct _Edje_External_Param_Info Edje_External_Param_Info; @@ -305,6 +311,8 @@ typedef struct _Edje_External_Param_Info Edje_External_Param_Info; {name, EDJE_EXTERNAL_PARAM_TYPE_STRING, {.s = {def, accept, deny}}} #define EDJE_EXTERNAL_PARAM_INFO_BOOL_FULL(name, def, false_str, true_str) \ {name, EDJE_EXTERNAL_PARAM_TYPE_BOOL, {.b = {def, false_str, true_str}}} +#define EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL(name, def, choices) \ + {name, EDJE_EXTERNAL_PARAM_TYPE_CHOICE, {.c = {def, choices}}} #define EDJE_EXTERNAL_PARAM_INFO_INT_DEFAULT(name, def) \ EDJE_EXTERNAL_PARAM_INFO_INT_FULL(name, def, EDJE_EXTERNAL_INT_UNSET, EDJE_EXTERNAL_INT_UNSET, EDJE_EXTERNAL_INT_UNSET) @@ -326,6 +334,22 @@ typedef struct _Edje_External_Param_Info Edje_External_Param_Info; #define EDJE_EXTERNAL_PARAM_INFO_SENTINEL {NULL, 0, {.s = {NULL, NULL, NULL}}} +/** + * @struct _Edje_External_Type information about an external type to be used. + * + * This structure provides information on how to display and modify a + * third party Evas_Object in Edje. + * + * Some function pointers are not really used by Edje, but provide + * means for Edje users to better interact with such objects. For + * instance, an editor may use label_get() and icon_get() to list all + * registered external types. + * + * @note The function pointers provided in this structure must check + * for errors and invalid or out-of-range values as for + * performance reasons Edje will not enforce hints provided as + * #Edje_External_Param_Info in the member parameters_info. + */ struct _Edje_External_Type { #define EDJE_EXTERNAL_TYPE_ABI_VERSION (2) @@ -547,6 +571,7 @@ extern "C" { EAPI Eina_Bool edje_external_param_double_get(const Eina_List *params, const char *key, double *ret); EAPI Eina_Bool edje_external_param_string_get(const Eina_List *params, const char *key, const char **ret); EAPI Eina_Bool edje_external_param_bool_get(const Eina_List *params, const char *key, Eina_Bool *ret); + EAPI Eina_Bool edje_external_param_choice_get(const Eina_List *params, const char *key, const char **ret); EAPI const Edje_External_Param_Info *edje_external_param_info_get(const char *type_name); EAPI const Edje_External_Type *edje_external_type_get(const char *type_name); diff --git a/src/lib/edje_edit.c b/src/lib/edje_edit.c index fb5c87c..9771ed9 100644 --- a/src/lib/edje_edit.c +++ b/src/lib/edje_edit.c @@ -2660,6 +2660,10 @@ edje_edit_state_add(Evas_Object *obj, const char *part, const char *name) case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: p->d = pi->info.d.def; break; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: + if (pi->info.c.def) + p->s = eina_stringshare_add(pi->info.c.def); + break; case EDJE_EXTERNAL_PARAM_TYPE_STRING: if (pi->info.s.def) p->s = eina_stringshare_add(pi->info.s.def); @@ -2838,6 +2842,7 @@ edje_edit_state_copy(Evas_Object *obj, const char *part, const char *from, const case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: new_p->d = p->d; break; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: case EDJE_EXTERNAL_PARAM_TYPE_STRING: new_p->s = eina_stringshare_add(p->s); break; @@ -3621,6 +3626,7 @@ edje_edit_state_external_param_get(Evas_Object *obj, const char *part, const cha case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: *value = &p->d; break; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: case EDJE_EXTERNAL_PARAM_TYPE_STRING: *value = (void *)p->s; break; @@ -3693,12 +3699,33 @@ edje_edit_state_external_param_string_get(Evas_Object *obj, const char *part, co return EINA_FALSE; } +EAPI Eina_Bool +edje_edit_state_external_param_choice_get(Evas_Object *obj, const char *part, const char *state, const char *param, const char **value) +{ + Eina_List *l; + Edje_External_Param *p; + GET_PD_OR_RETURN(EINA_FALSE); + + EINA_LIST_FOREACH(pd->external_params, l, p) + if (!strcmp(p->name, param)) + { + if (p->type != EDJE_EXTERNAL_PARAM_TYPE_CHOICE) + return EINA_FALSE; + if (value) + *value = p->s; + return EINA_TRUE; + } + + return EINA_FALSE; +} + /** * Arguments should have proper sized values matching their types: * - EDJE_EXTERNAL_PARAM_TYPE_INT: int * - EDJE_EXTERNAL_PARAM_TYPE_BOOL: int * - EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: double * - EDJE_EXTERNAL_PARAM_TYPE_STRING: char* + * - EDJE_EXTERNAL_PARAM_TYPE_CHOICE: char* */ EAPI Eina_Bool edje_edit_state_external_param_set(Evas_Object *obj, const char *part, const char *state, const char *param, Edje_External_Param_Type type, ...) @@ -3748,6 +3775,7 @@ edje_edit_state_external_param_set(Evas_Object *obj, const char *part, const cha case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: p->d = (double)va_arg(ap, double); break; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: case EDJE_EXTERNAL_PARAM_TYPE_STRING: p->s = eina_stringshare_add((const char *)va_arg(ap, char *)); break; @@ -3786,6 +3814,12 @@ edje_edit_state_external_param_string_set(Evas_Object *obj, const char *part, co return edje_edit_state_external_param_set(obj, part, state, param, EDJE_EXTERNAL_PARAM_TYPE_STRING, value); } +EAPI Eina_Bool +edje_edit_state_external_param_choice_set(Evas_Object *obj, const char *part, const char *state, const char *param, const char *value) +{ + return edje_edit_state_external_param_set(obj, part, state, param, EDJE_EXTERNAL_PARAM_TYPE_CHOICE, value); +} + /**************/ /* TEXT API */ /**************/ @@ -6057,7 +6091,16 @@ _edje_generate_source_of_state(Evas_Object *obj, const char *part, const char *s break; case EDJE_EXTERNAL_PARAM_TYPE_STRING: if (p->s) - fprintf(f, I6"string: \"%s\" \"%s\";\n", p->name, p->s); + fprintf(f, I6"string: \"%s\" \"%s\";\n", + p->name, p->s); + break; + case EDJE_EXTERNAL_PARAM_TYPE_BOOL: + fprintf(f, I6"bool: \"%s\" \"%d\";\n", p->name, p->i); + break; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: + if (p->s) + fprintf(f, I6"choice: \"%s\" \"%s\";\n", + p->name, p->s); break; default: break; diff --git a/src/lib/edje_embryo.c b/src/lib/edje_embryo.c index ada4b21..492118a 100644 --- a/src/lib/edje_embryo.c +++ b/src/lib/edje_embryo.c @@ -218,6 +218,9 @@ void *alloca (size_t); * external_param_get_strlen(id, param_name[]) * external_param_get_str(id, param_name[], value[], value_maxlen) * external_param_set_str(id, param_name[], value[]) + * external_param_get_choice_strlen(id, param_name[]) + * external_param_get_choice(id, param_name[], value[], value_maxlen) + * external_param_set_choice(id, param_name[], value[]) * external_param_get_bool(id, param_name[]) * external_param_set_bool(id, param_name[], value) * @@ -2502,6 +2505,107 @@ _edje_embryo_fn_external_param_set_str(Embryo_Program *ep, Embryo_Cell *params) return _edje_external_param_set(rp->swallowed_object, &eep); } +/* external_param_get_choice_strlen(id, param_name[]) */ +static Embryo_Cell +_edje_embryo_fn_external_param_get_choice_strlen(Embryo_Program *ep, Embryo_Cell *params) +{ + Edje *ed; + int part_id; + Edje_Real_Part *rp; + Edje_External_Param eep; + char *param_name; + + CHKPARAM(2); + ed = embryo_program_data_get(ep); + + part_id = params[1]; + if (part_id < 0) return 0; + rp = ed->table_parts[part_id % ed->table_parts_size]; + + GETSTR(param_name, params[2]); + if (!param_name) return 0; + eep.name = param_name; + eep.type = EDJE_EXTERNAL_PARAM_TYPE_CHOICE; + eep.s = NULL; + _edje_external_param_get(rp->swallowed_object, &eep); + if (!eep.s) return 0; + return strlen(eep.s); +} + +/* external_param_get_choice(id, param_name[], val[], val_maxlen) */ +static Embryo_Cell +_edje_embryo_fn_external_param_get_choice(Embryo_Program *ep, Embryo_Cell *params) +{ + Edje *ed; + int part_id; + Edje_Real_Part *rp; + Edje_External_Param eep; + char *param_name; + size_t src_len, dst_len; + + CHKPARAM(4); + dst_len = params[4]; + if (dst_len < 1) goto error; + + ed = embryo_program_data_get(ep); + + part_id = params[1]; + if (part_id < 0) goto error; + rp = ed->table_parts[part_id % ed->table_parts_size]; + + GETSTR(param_name, params[2]); + if (!param_name) return 0; + eep.name = param_name; + eep.type = EDJE_EXTERNAL_PARAM_TYPE_CHOICE; + eep.s = NULL; + _edje_external_param_get(rp->swallowed_object, &eep); + if (!eep.s) goto error; + src_len = strlen(eep.s); + if (src_len < dst_len) + { + SETSTR(eep.s, params[3]); + } + else + { + char *tmp = alloca(dst_len); + memcpy(tmp, eep.s, dst_len - 1); + tmp[dst_len] = '\0'; + SETSTR(tmp, params[3]); + } + return 1; + + error: + SETSTR("", params[3]); + return 0; +} + +/* external_param_set_choice(id, param_name[], val[]) */ +static Embryo_Cell +_edje_embryo_fn_external_param_set_choice(Embryo_Program *ep, Embryo_Cell *params) +{ + Edje *ed; + int part_id; + Edje_Real_Part *rp; + Edje_External_Param eep; + char *param_name, *val; + + CHKPARAM(3); + ed = embryo_program_data_get(ep); + + part_id = params[1]; + if (part_id < 0) return 0; + rp = ed->table_parts[part_id % ed->table_parts_size]; + + GETSTR(param_name, params[2]); + if (!param_name) return 0; + eep.name = param_name; + eep.type = EDJE_EXTERNAL_PARAM_TYPE_CHOICE; + GETSTR(val, params[3]); + if (!val) return 0; + eep.s = val; + return _edje_external_param_set(rp->swallowed_object, &eep); +} + /* external_param_get_bool(id, param_name[]) */ static Embryo_Cell _edje_embryo_fn_external_param_get_bool(Embryo_Program *ep, Embryo_Cell *params) diff --git a/src/lib/edje_external.c b/src/lib/edje_external.c index 1512942..1356a8b 100644 --- a/src/lib/edje_external.c +++ b/src/lib/edje_external.c @@ -28,6 +28,8 @@ edje_external_param_type_str(Edje_External_Param_Type type) return "STRING"; case EDJE_EXTERNAL_PARAM_TYPE_BOOL: return "BOOL"; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: + return "CHOICE"; default: return "(unknown)"; } @@ -92,6 +94,12 @@ edje_object_part_external_object_get(const Evas_Object *obj, const char *part) * function. The interpretation of how state_set parameters and * param_set will interact is up to the external plugin. * + * @note this function will not check if parameter value is valid + * using #Edje_External_Param_Info minimum, maximum, valid + * choices and others. However these should be checked by the + * underlying implementation provided by the external + * plugin. This is done for performance reasons. + * * @param obj A valid Evas_Object handle * @param part The part name * @param param the parameter details, including its name, type and @@ -452,6 +460,23 @@ edje_external_param_bool_get(const Eina_List *params, const char *key, Eina_Bool return EINA_FALSE; } +EAPI Eina_Bool +edje_external_param_choice_get(const Eina_List *params, const char *key, const char **ret) +{ + Edje_External_Param *param; + + if (!params) return EINA_FALSE; + param = edje_external_param_find(params, key); + + if (param && param->type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE && ret) + { + *ret = param->s; + return EINA_TRUE; + } + + return EINA_FALSE; +} + /** * Get the array of parameters information about a type given its name. * diff --git a/src/lib/edje_program.c b/src/lib/edje_program.c index 67fdcaa..5002fb7 100644 --- a/src/lib/edje_program.c +++ b/src/lib/edje_program.c @@ -1358,17 +1358,6 @@ _edje_param_external_get(const Evas_Object *obj, const char *name, Edje_External return param; } -static Edje_External_Param_Type -_edje_param_external_type_get(const Evas_Object *obj, const char *name) -{ - const Edje_External_Param_Info *info; - - info = _edje_external_param_info_get(obj, name); - if (!info) return EDJE_EXTERNAL_PARAM_TYPE_MAX; - - return info->type; -} - /* simulate external properties for native objects */ static Edje_External_Param * _edje_param_native_get(Edje_Real_Part *rp, const char *name, Edje_External_Param *param, void **free_ptr) @@ -1688,19 +1677,32 @@ _edje_param_native_set(Edje_Real_Part *rp, const char *name, const Edje_External return EINA_FALSE; } -static Edje_External_Param_Type -_edje_param_native_type_get(const Edje_Real_Part *rp, const char *name) +static const Edje_External_Param_Info * +_edje_native_param_info_get(const Edje_Real_Part *rp, const char *name) { if ((rp->part->type == EDJE_PART_TYPE_TEXT) || (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)) { - if (!strcmp(name, "text")) return EDJE_EXTERNAL_PARAM_TYPE_STRING; + if (!strcmp(name, "text")) + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_STRING("text"); + return π + } if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) { if (!strcmp(name, "text_unescaped")) - return EDJE_EXTERNAL_PARAM_TYPE_STRING; + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_STRING("text_unescaped"); + return π + } if (!strcmp(name, "select_allow")) - return EDJE_EXTERNAL_PARAM_TYPE_BOOL; + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_BOOL("text_unescaped"); + return π + } } } @@ -1709,29 +1711,68 @@ _edje_param_native_type_get(const Edje_Real_Part *rp, const char *name) if (!strncmp(name, "drag_", sizeof("drag_") - 1)) { name += sizeof("drag_") - 1; - if ((!strcmp(name, "value_x")) || - (!strcmp(name, "value_y")) || - (!strcmp(name, "size_w")) || - (!strcmp(name, "size_h")) || - (!strcmp(name, "step_x")) || - (!strcmp(name, "step_y")) || - (!strcmp(name, "page_x")) || - (!strcmp(name, "page_y"))) - return EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; - else - return EDJE_EXTERNAL_PARAM_TYPE_MAX; + if (!strcmp(name, "value_x")) + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_value_x"); + return π + } + if (!strcmp(name, "value_y")) + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_value_y"); + return π + } + if (!strcmp(name, "size_w")) + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_size_w"); + return π + } + if (!strcmp(name, "size_h")) + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_size_h"); + return π + } + if (!strcmp(name, "step_x")) + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_step_x"); + return π + } + if (!strcmp(name, "step_y")) + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_step_y"); + return π + } + if (!strcmp(name, "page_x")) + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_page_x"); + return π + } + if (!strcmp(name, "page_y")) + { + static const Edje_External_Param_Info pi = + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_page_y"); + return π + } + + return NULL; } } - return EDJE_EXTERNAL_PARAM_TYPE_MAX; + return NULL; } static Edje_External_Param * -_edje_param_convert(Edje_External_Param *param, Edje_External_Param_Type type) +_edje_param_convert(Edje_External_Param *param, const Edje_External_Param_Info *dst_info) { - if (param->type == type) return param; + if (param->type == dst_info->type) return param; - switch (type) + switch (dst_info->type) { case EDJE_EXTERNAL_PARAM_TYPE_BOOL: case EDJE_EXTERNAL_PARAM_TYPE_INT: @@ -1743,14 +1784,18 @@ _edje_param_convert(Edje_External_Param *param, Edje_External_Param_Type type) i = (int)param->d; break; case EDJE_EXTERNAL_PARAM_TYPE_STRING: + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: i = (param->s) ? atoi(param->s) : 0; break; case EDJE_EXTERNAL_PARAM_TYPE_BOOL: + case EDJE_EXTERNAL_PARAM_TYPE_INT: i = param->i; default: return NULL; } - param->type = type; + if (dst_info->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL) + i = !!i; + param->type = dst_info->type; param->i = i; return param; } @@ -1764,6 +1809,7 @@ _edje_param_convert(Edje_External_Param *param, Edje_External_Param_Type type) d = (double)param->i; break; case EDJE_EXTERNAL_PARAM_TYPE_STRING: + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: d = (param->s) ? atof(param->s) : 0.0; break; case EDJE_EXTERNAL_PARAM_TYPE_BOOL: @@ -1771,7 +1817,7 @@ _edje_param_convert(Edje_External_Param *param, Edje_External_Param_Type type) default: return NULL; } - param->type = type; + param->type = dst_info->type; param->d = d; return param; } @@ -1788,35 +1834,117 @@ _edje_param_convert(Edje_External_Param *param, Edje_External_Param_Type type) case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: if (!snprintf(s, sizeof(s), "%f", param->d)) return NULL; break; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: + param->type = dst_info->type; + return param; default: return NULL; } - param->type = type; + param->type = dst_info->type; param->s = s; return param; } + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: + { + static char s[64]; + const char *val; + switch (param->type) + { + case EDJE_EXTERNAL_PARAM_TYPE_BOOL: + case EDJE_EXTERNAL_PARAM_TYPE_INT: + if (!snprintf(s, sizeof(s), "%i", param->i)) return NULL; + val = s; + break; + case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: + if (!snprintf(s, sizeof(s), "%f", param->d)) return NULL; + val = s; + break; + case EDJE_EXTERNAL_PARAM_TYPE_STRING: + val = param->s; + break; + default: + return NULL; + } + + param->type = dst_info->type; + if (param->s != val) param->s = val; + return param; + } + default: return NULL; } } +static Eina_Bool +_edje_param_validate(const Edje_External_Param *param, const Edje_External_Param_Info *info) +{ + switch (info->type) + { + case EDJE_EXTERNAL_PARAM_TYPE_BOOL: + return ((param->i == 0) || (param->i == 1)); + + case EDJE_EXTERNAL_PARAM_TYPE_INT: + if ((info->info.i.min != EDJE_EXTERNAL_INT_UNSET) && + (info->info.i.min > param->i)) + return EINA_FALSE; + + if ((info->info.i.max != EDJE_EXTERNAL_INT_UNSET) && + (info->info.i.max < param->i)) + return EINA_FALSE; + + return EINA_TRUE; + + case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: + if ((info->info.d.min != EDJE_EXTERNAL_DOUBLE_UNSET) && + (info->info.d.min > param->d)) + return EINA_FALSE; + + if ((info->info.d.max != EDJE_EXTERNAL_DOUBLE_UNSET) && + (info->info.d.max < param->d)) + return EINA_FALSE; + + return EINA_TRUE; + + case EDJE_EXTERNAL_PARAM_TYPE_STRING: + if (!param->s) return EINA_FALSE; + if (info->info.s.accept_fmt) + INF("string 'accept_fmt' validation not implemented."); + if (info->info.s.deny_fmt) + INF("string 'deny_fmt' validation not implemented."); + return EINA_TRUE; + + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: + { + const char **itr = info->info.c.choices; + if (!itr) return EINA_FALSE; + for (; *itr != NULL; itr++) + if (!strcmp(*itr, param->s)) + return EINA_TRUE; + return EINA_FALSE; + } + + default: return EINA_FALSE; + } +} + static void _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part *dst_part, const char *dst_param) { Edje_External_Param val; - Edje_External_Param_Type dst_type; + const Edje_External_Param_Info *dst_info; void *free_ptr = NULL; if ((!src_part) || (!src_param) || (!dst_part) || (!dst_param)) return; if (dst_part->part->type == EDJE_PART_TYPE_EXTERNAL) - dst_type = _edje_param_external_type_get + dst_info = _edje_external_param_info_get (dst_part->swallowed_object, dst_param); else - dst_type = _edje_param_native_type_get(dst_part, dst_param); + dst_info = _edje_native_param_info_get(dst_part, dst_param); - if (dst_type == EDJE_EXTERNAL_PARAM_TYPE_MAX) + if (!dst_info) { ERR("cannot copy, invalid destination parameter '%s' of part '%s'", dst_param, dst_part->part->name); @@ -1843,11 +1971,18 @@ _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part } } - if (!_edje_param_convert(&val, dst_type)) + if (!_edje_param_convert(&val, dst_info)) { ERR("cannot convert parameter type %s to requested type %s", edje_external_param_type_str(val.type), - edje_external_param_type_str(dst_type)); + edje_external_param_type_str(dst_info->type)); + goto end; + } + + if (!_edje_param_validate(&val, dst_info)) + { + ERR("incorrect parameter value failed validation for type %s", + edje_external_param_type_str(dst_info->type)); goto end; } @@ -1857,7 +1992,7 @@ _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part if (!_edje_external_param_set(dst_part->swallowed_object, &val)) { ERR("failed to set parameter '%s' (%s) of part '%s'", - dst_param, edje_external_param_type_str(dst_type), + dst_param, edje_external_param_type_str(dst_info->type), dst_part->part->name); goto end; } @@ -1867,7 +2002,7 @@ _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part if (!_edje_param_native_set(dst_part, dst_param, &val)) { ERR("failed to set parameter '%s' (%s) of part '%s'", - dst_param, edje_external_param_type_str(dst_type), + dst_param, edje_external_param_type_str(dst_info->type), dst_part->part->name); goto end; } -- 2.7.4