diff --git a/src/bin/edje/edje_cc.h b/src/bin/edje/edje_cc.h index 1ee0362ba2..a097d8eb1e 100644 --- a/src/bin/edje/edje_cc.h +++ b/src/bin/edje/edje_cc.h @@ -220,6 +220,7 @@ int get_arg_count(void); void check_arg_count(int n); void check_min_arg_count(int n); int check_range_arg_count(int n, int m); +int param_had_quote(int n); int object_handler_num(void); int object_handler_short_num(void); diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c index a4b85cd81c..00eb2365de 100644 --- a/src/bin/edje/edje_cc_handlers.c +++ b/src/bin/edje/edje_cc_handlers.c @@ -478,13 +478,14 @@ static void st_collections_group_parts_part_api(void); /* external part parameters */ static void st_collections_group_parts_part_description_params_int(void); -static void ob_collections_group_programs_program(void); 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_parts_part_description_params_smart(void); + +static void ob_collections_group_programs_program(void); +static void st_collections_group_programs_program_name(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); @@ -963,6 +964,7 @@ New_Statement_Handler statement_handlers[] = {"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.params.*", st_collections_group_parts_part_description_params_smart}, IMAGE_STATEMENTS("collections.group.parts.part.description.") {"collections.group.parts.part.description.font", st_fonts_font}, /* dup */ FONT_STYLE_CC_STATEMENTS("collections.group.parts.part.description.") @@ -1149,6 +1151,163 @@ New_Statement_Handler statement_handlers_short_single[] = {"collections.group.parts.part.description.inherit", st_collections_group_parts_part_description_inherit}, }; +/** @edcsubsection{lazedc_external_params, + * LazEDC Group.Parts.External.Desc.Params} */ + +/** + @page edcref + @block + params + @context + ... + external { + desc { "default"; + params { + number: 10; -> int: "number" 10; + number2: 1.1; -> double: "number2" 1.1; + label: "OK"; -> string: "label" "OK"; + check: true; -> bool: "check" 1; + check2: false; -> bool: "check2" 0; + text_wrap: mixed; -> choice: "text_wrap" "mixed"; + } + } + } + ... + @description + The name of parameter can be used as a statement keyword in params block. + The type of parameter is determined automatically by the value, + so it should follow the next rules. + Number without decimal point is considered as an integer. + Number with decimal point is considered as a double. + Double-quoted string is considered as a string. + 'true' or 'false' without quotes is considred as a boolean. + String without quotes except for 'true' or 'false' is considered as a choice. + @since 1.18 + @endblock +*/ +static Edje_External_Param_Type +_parse_external_param_type(char *token) +{ + Eina_Bool num, point; + char *begin; + + if (param_had_quote(0)) + return EDJE_EXTERNAL_PARAM_TYPE_STRING; + + num = EINA_TRUE; + point = EINA_FALSE; + begin = token; + + while (*token) + { + if ((*token < '0') || (*token > '9')) + { + if ((!point) && (*token == '.')) + { + point = EINA_TRUE; + } + else + { + num = EINA_FALSE; + break; + } + } + token++; + } + + if (num) + { + if (!point) + return EDJE_EXTERNAL_PARAM_TYPE_INT; + else + return EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; + } + else + { + if (!strcmp(begin, "true") || !strcmp(begin, "false")) + return EDJE_EXTERNAL_PARAM_TYPE_BOOL; + else + return EDJE_EXTERNAL_PARAM_TYPE_CHOICE; + } +} + +static void +st_collections_group_parts_part_description_params_smart(void) +{ + Edje_Part_Description_External *ed; + Edje_External_Param *param; + Eina_List *l; + char *last, *name, *token; + int found = 0; + + check_arg_count(1); + + if (current_part->type != EDJE_PART_TYPE_EXTERNAL) + { + ERR("parse error %s:%i. params in non-EXTERNAL part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_External*) current_desc; + + last = eina_list_last_data_get(stack); + if (!strncmp(last, "params.", strlen("params."))) + name = strdup(last + strlen("params.")); + else + name = strdup(last); + + /* if a param with this name already exists, overwrite it */ + EINA_LIST_FOREACH(ed->external_params, l, param) + { + if (!strcmp(param->name, name)) + { + found = 1; + break; + } + } + + if (!found) + { + param = mem_alloc(SZ(Edje_External_Param)); + param->name = name; + } + + token = parse_str(0); + + param->type = _parse_external_param_type(token); + param->i = 0; + param->d = 0; + param->s = NULL; + + switch (param->type) + { + case EDJE_EXTERNAL_PARAM_TYPE_BOOL: + if (!strcmp(token, "true")) + param->i = 1; + else if (!strcmp(token, "false")) + param->i = 0; + break; + case EDJE_EXTERNAL_PARAM_TYPE_INT: + param->i = parse_int(0); + break; + case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: + param->d = parse_float(0); + break; + case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: + case EDJE_EXTERNAL_PARAM_TYPE_STRING: + param->s = parse_str(0); + break; + default: + ERR("parse error %s:%i. Invalid param type.", + file_in, line - 1); + break; + } + + if (!found) + ed->external_params = eina_list_append(ed->external_params, param); +} + #define PROGRAM_OBJECTS(PREFIX) \ {PREFIX".program", ob_collections_group_programs_program}, /* dup */ \ {PREFIX".program.script", ob_collections_group_programs_program_script}, /* dup */ \ diff --git a/src/bin/edje/edje_cc_parse.c b/src/bin/edje/edje_cc_parse.c index 542079a689..4c860b5dba 100644 --- a/src/bin/edje/edje_cc_parse.c +++ b/src/bin/edje/edje_cc_parse.c @@ -65,6 +65,7 @@ int line = 0; Eina_List *stack = NULL; Eina_Array params; int had_quote = 0; +int params_quote = 0; static char file_buf[4096]; static int did_wildcard = 0; @@ -210,6 +211,19 @@ new_object(void) sh = eina_hash_find(_new_statement_short_hash, id); if (!sh) sh = eina_hash_find(_new_statement_short_single_hash, id); + if (!sh) + { + char buf[512] = { 0, }; + char *end; + + strcpy(buf, id); + end = strrchr(buf, '.'); + if (end) end++; + else end = buf; + + strcpy(end, "*"); + sh = eina_hash_find(_new_statement_hash, buf); + } if ((!sh) && (!did_wildcard) && (!had_quote)) { ERR("%s:%i unhandled keyword %s", @@ -239,11 +253,29 @@ new_statement(void) } else { - ERR("%s:%i unhandled keyword %s", - file_in, line - 1, - (char *)eina_list_data_get(eina_list_last(stack))); - err_show(); - exit(-1); + char buf[512] = { 0, }; + char *end; + + strcpy(buf, id); + end = strrchr(buf, '.'); + if (end) end++; + else end = buf; + + strcpy(end, "*"); + sh = eina_hash_find(_new_statement_hash, buf); + + if (sh) + { + if (sh->func) sh->func(); + } + else + { + ERR("%s:%i unhandled keyword %s", + file_in, line - 1, + (char *)eina_list_data_get(eina_list_last(stack))); + err_show(); + exit(-1); + } } } @@ -729,6 +761,7 @@ parse(char *data, off_t size) /* clear out params */ while ((param = eina_array_pop(¶ms))) free(param); + params_quote = 0; /* remove top from stack */ stack_pop(); } @@ -775,10 +808,14 @@ parse(char *data, off_t size) { if (do_params) { + if (had_quote) + params_quote |= (1 << eina_array_count(¶ms)); eina_array_push(¶ms, token); } else if (do_indexes) { + if (had_quote) + params_quote |= (1 << eina_array_count(¶ms)); do_indexes++; eina_array_push(¶ms, token); } @@ -1868,3 +1905,9 @@ get_param_index(char *str) return -1; } + +int +param_had_quote(int n) +{ + return (params_quote & (1 << n)); +}