diff --git a/src/bin/edje/edje_cc.h b/src/bin/edje/edje_cc.h index aa49caa8a4..84d8223fe1 100644 --- a/src/bin/edje/edje_cc.h +++ b/src/bin/edje/edje_cc.h @@ -194,6 +194,7 @@ void data_queue_spectrum_slave_lookup(int *master, int *slave); void data_process_lookups(void); void data_process_scripts(void); void data_process_script_lookups(void); +void process_color_tree(char *s, const char *file_in, int line); void part_description_image_cleanup(Edje_Part *ep); @@ -252,6 +253,8 @@ void edje_cc_handlers_hierarchy_free(void); void edje_cc_handlers_pop_notify(const char *token); int get_param_index(char *str); +void color_tree_root_free(void); + /* global vars */ extern Eina_List *ext_dirs; extern Eina_List *img_dirs; @@ -297,6 +300,7 @@ extern int compress_mode; extern int threads; extern int annotate; extern Eina_Bool current_group_inherit; +extern Eina_List *color_tree_root; extern int had_quote; diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c index f5fd9408c7..20420642cb 100644 --- a/src/bin/edje/edje_cc_handlers.c +++ b/src/bin/edje/edje_cc_handlers.c @@ -216,6 +216,8 @@ static void st_styles_style_name(void); static void st_styles_style_base(void); static void st_styles_style_tag(void); +static void ob_color_tree(void); + static void ob_color_class(void); static void st_color_class_name(void); static void st_color_class_color(void); @@ -1172,6 +1174,7 @@ New_Object_Handler object_handlers[] = {"data", NULL}, {"styles", NULL}, {"styles.style", ob_styles_style}, + {"color_tree", ob_color_tree}, {"color_classes", NULL}, {"color_classes.color_class", ob_color_class}, {"text_classes", NULL}, @@ -1192,6 +1195,7 @@ New_Object_Handler object_handlers[] = {"collections.fonts", NULL}, /* dup */ {"collections.styles", NULL}, /* dup */ {"collections.styles.style", ob_styles_style}, /* dup */ + {"collections.color_tree", ob_color_tree}, /* dup */ {"collections.color_classes", NULL}, /* dup */ {"collections.color_classes.color_class", ob_color_class}, /* dup */ {"collections.text_classes", NULL}, @@ -1228,6 +1232,7 @@ New_Object_Handler object_handlers[] = {"collections.group.fonts", NULL}, /* dup */ {"collections.group.styles", NULL}, /* dup */ {"collections.group.styles.style", ob_styles_style}, /* dup */ + {"collections.group.color_tree", ob_color_tree}, /* dup */ {"collections.group.color_classes", NULL}, /* dup */ {"collections.group.color_classes.color_class", ob_color_class}, /* dup */ {"collections.group.text_classes", NULL}, @@ -2644,6 +2649,49 @@ st_data_file(void) free(filename); } +/** @edcsubsection{toplevel_color_tree, + * Color Tree} */ + +/** + @page edcref + @block + color_tree + @context + color_tree { + "color_class_0" { + "color_class_3"; + "color_class_4" { + "color_class_5"; + "color_class_6"; + } + } + "color_class_1"; + "color_class_2"; + .. + } + @description + The "color_tree" block contains color tree node blocks. + Each node block begins with the name of color class and enclosed with braces. + Node block can be placed within another node block. + @endblock +*/ +static void +ob_color_tree(void) +{ + if (!is_verbatim()) track_verbatim(1); + else + { + char *s; + + s = get_verbatim(); + if (s) + { + process_color_tree(s, file_in, get_verbatim_line1()); + set_verbatim(NULL, 0, 0); + } + } +} + /** @edcsubsection{toplevel_color_classes, * Color Classes} */ diff --git a/src/bin/edje/edje_cc_out.c b/src/bin/edje/edje_cc_out.c index cc11fad5e0..ea1c190831 100644 --- a/src/bin/edje/edje_cc_out.c +++ b/src/bin/edje/edje_cc_out.c @@ -220,6 +220,7 @@ Eina_List *fonts = NULL; Eina_List *codes = NULL; Eina_List *code_lookups = NULL; Eina_List *aliases = NULL; +Eina_List *color_tree_root = NULL; static Eet_Data_Descriptor *edd_edje_file = NULL; static Eet_Data_Descriptor *edd_edje_part_collection = NULL; @@ -4139,3 +4140,143 @@ needed_part_exists(Edje_Part_Collection *pc, const char *name) } return found; } + +void +color_tree_root_free(void) +{ + char *name; + + EINA_LIST_FREE(color_tree_root, name) + free(name); +} + +char * +color_tree_token_next(char *dst, char *src, int *line) +{ + Eina_Bool begin = EINA_FALSE, next = EINA_FALSE; + + while (!next) + { + if (*src == '\0') break; + + if (*src == '"') + { + if (!begin) begin = EINA_TRUE; + else next = EINA_TRUE; + } + else if ((!begin) && ((*src == '{') || (*src == '}') || (*src == ';'))) + { + *dst++ = *src; + next = EINA_TRUE; + } + else if ((!begin) && (*src == '\n')) + { + (*line)++; + } + else if (begin) + { + *dst++ = *src; + } + src++; + } + *dst = '\0'; + return src; +} + +Edje_Color_Tree_Node * +color_tree_parent_node_get(const char *color_class) +{ + Edje_Color_Tree_Node *ctn; + Eina_List *l, *ll; + char *name; + + EINA_LIST_FOREACH(edje_file->color_tree, l, ctn) + if (ctn->color_classes) + EINA_LIST_FOREACH(ctn->color_classes, ll, name) + if (!strcmp(name, color_class)) + return ctn; + + return NULL; +} + +void +process_color_tree(char *s, const char *file_in, int line) +{ + char token[2][1024]; + int id = 0; + Eina_Array *array; + Edje_Color_Tree_Node *ctn; + Eina_List *l; + char *name; + + array = eina_array_new(4); + + if (!s) return; + + do + { + s = color_tree_token_next(token[id], s, &line); + + if (!strcmp(token[id], "{")) + { + if (!token[!id][0]) + error_and_abort(NULL, "parse error %s:%i. color class is not set to newly opened node block.", + file_in, line - 1); + + ctn = mem_alloc(SZ(Edje_Color_Tree_Node)); + ctn->name = strdup(token[!id]); + ctn->color_classes = NULL; + + edje_file->color_tree = eina_list_append(edje_file->color_tree, ctn); + + eina_array_push(array, ctn); + token[id][0] = '\0'; + } + else if (!strcmp(token[id], "}")) + { + eina_array_pop(array); + token[id][0] = '\0'; + } + else if (!strcmp(token[id], ";")) + { + token[id][0] = '\0'; + } + else if (*s != '\0') + { + if (eina_array_count(array)) + { + if (color_tree_root) + EINA_LIST_FOREACH(color_tree_root, l, name) + if (!strcmp(name, token[id])) + { + error_and_abort(NULL, "parse error %s:%i. The color class \"%s\" already belongs to the root node.", + file_in, line -1, token[id]); + } + + if ((ctn = color_tree_parent_node_get(token[id]))) + error_and_abort(NULL, "parse error %s:%i. The color class \"%s\" already belongs to the \"%s\" node.", + file_in, line -1, token[id], ctn->name); + + ctn = eina_array_data_get(array, eina_array_count(array) - 1); + ctn->color_classes = eina_list_append(ctn->color_classes, strdup(token[id])); + } + else + { + if ((ctn = color_tree_parent_node_get(token[id]))) + error_and_abort(NULL, "parse error %s:%i. The color class \"%s\" already belongs to the \"%s\" node.", + file_in, line -1, token[id], ctn->name); + + color_tree_root = eina_list_append(color_tree_root, strdup(token[id])); + } + } + + id = !id; + + } while (*s); + + if (eina_array_count(array)) + error_and_abort(NULL, "parse error %s:%i. check pair of parens.", file_in, line - 1); + + eina_array_clean(array); + eina_array_free(array); +} diff --git a/src/bin/edje/edje_cc_parse.c b/src/bin/edje/edje_cc_parse.c index 4466c8729d..c7ea53a723 100644 --- a/src/bin/edje/edje_cc_parse.c +++ b/src/bin/edje/edje_cc_parse.c @@ -1045,6 +1045,7 @@ compile(void) eina_array_flush(¶ms); eina_strbuf_free(stack_buf); stack_buf = NULL; + color_tree_root_free(); } else { diff --git a/src/lib/edje/edje_cache.c b/src/lib/edje/edje_cache.c index 526324ed83..e6e99b43c7 100644 --- a/src/lib/edje/edje_cache.c +++ b/src/lib/edje/edje_cache.c @@ -261,12 +261,14 @@ _edje_file_coll_open(Edje_File *edf, const char *coll) static Edje_File * _edje_file_open(const Eina_File *f, int *error_ret, time_t mtime, Eina_Bool coll) { + Edje_Color_Tree_Node *ctn; Edje_Color_Class *cc; Edje_Text_Class *tc; Edje_Size_Class *sc; Edje_File *edf; - Eina_List *l; + Eina_List *l, *ll; Eet_File *ef; + char *name; ef = eet_mmap(f); if (!ef) @@ -315,6 +317,12 @@ _edje_file_open(const Eina_File *f, int *error_ret, time_t mtime, Eina_Bool coll /* This should be done at edje generation time */ _edje_textblock_style_parse_and_fix(edf); + + edf->color_tree_hash = eina_hash_string_small_new(NULL); + EINA_LIST_FOREACH(edf->color_tree, l, ctn) + EINA_LIST_FOREACH(ctn->color_classes, ll, name) + eina_hash_add(edf->color_tree_hash, name, ctn); + edf->color_hash = eina_hash_string_small_new(NULL); EINA_LIST_FOREACH(edf->color_classes, l, cc) if (cc->name) diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index 17046708b8..ce2652ba15 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -2762,7 +2762,7 @@ _edje_part_recalc_single(Edje *ed, if (ep->part->type != EDJE_PART_TYPE_SPACER) { if ((desc->color_class) && (*desc->color_class)) - cc = _edje_color_class_find(ed, desc->color_class); + cc = _edje_color_class_recursive_find(ed, desc->color_class); if (cc) { diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index 18e014e7e6..4eaaec9592 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -6,6 +6,7 @@ EAPI Eet_Data_Descriptor * _edje_edd_edje_part_collection = NULL; Eet_Data_Descriptor *_edje_edd_edje_string = NULL; Eet_Data_Descriptor *_edje_edd_edje_style = NULL; Eet_Data_Descriptor *_edje_edd_edje_style_tag = NULL; +Eet_Data_Descriptor *_edje_edd_edje_color_tree_node = NULL; Eet_Data_Descriptor *_edje_edd_edje_color_class = NULL; Eet_Data_Descriptor *_edje_edd_edje_text_class = NULL; Eet_Data_Descriptor *_edje_edd_edje_size_class = NULL; @@ -521,6 +522,12 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_style, Edje_Style, "name", name, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_style, Edje_Style, "tags", tags, _edje_edd_edje_style_tag); + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Color_Tree_Node); + _edje_edd_edje_color_tree_node = + eet_data_descriptor_file_new(&eddc); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_color_tree_node, Edje_Color_Tree_Node, "name", name, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_LIST_STRING(_edje_edd_edje_color_tree_node, Edje_Color_Tree_Node, "color_classes", color_classes); + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Color_Class); _edje_edd_edje_color_class = eet_data_descriptor_file_new(&eddc); @@ -579,6 +586,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_file, Edje_File, "vibration_dir", vibration_dir, _edje_edd_edje_vibration_directory); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_file, Edje_File, "styles", styles, _edje_edd_edje_style); + EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_file, Edje_File, "color_tree", color_tree, _edje_edd_edje_color_tree_node); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_file, Edje_File, "color_classes", color_classes, _edje_edd_edje_color_class); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_file, Edje_File, "text_classes", text_classes, _edje_edd_edje_text_class); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_file, Edje_File, "size_classes", size_classes, _edje_edd_edje_size_class); diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 4f0e070ee4..a3385421d4 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -1682,6 +1682,7 @@ _edje_file_del(Edje *ed) void _edje_file_free(Edje_File *edf) { + Edje_Color_Tree_Node *ectn; Edje_Color_Class *ecc; Edje_Text_Class *etc; Edje_Size_Class *esc; @@ -1777,6 +1778,14 @@ _edje_file_free(Edje_File *edf) free(edf->external_dir); } + eina_hash_free(edf->color_tree_hash); + EINA_LIST_FREE(edf->color_tree, ectn) + { + if (edf->free_strings && ectn->name) eina_stringshare_del(ectn->name); + eina_list_free(ectn->color_classes); + free(ectn); + } + eina_hash_free(edf->color_hash); EINA_LIST_FREE(edf->color_classes, ecc) { diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index fe82a6c921..75f9a7fcec 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -328,6 +328,7 @@ typedef struct _Edje_Mo Edje_Mo; typedef struct _Edje_Mo_Directory Edje_Mo_Directory; typedef struct _Edje_Gfx_Filter Edje_Gfx_Filter; typedef struct _Edje_Gfx_Filter_Directory Edje_Gfx_Filter_Directory; +typedef struct _Edje_Color_Tree_Node Edje_Color_Tree_Node; typedef struct _Edje_Vibration_Sample Edje_Vibration_Sample; typedef struct _Edje_Vibration_Directory Edje_Vibration_Directory; @@ -539,6 +540,9 @@ struct _Edje_File Eina_List *styles; + Eina_List *color_tree; + Eina_Hash *color_tree_hash; + Eina_List *color_classes; Eina_Hash *color_hash; @@ -741,6 +745,12 @@ struct _Edje_Gfx_Filter_Directory int filters_count; }; +struct _Edje_Color_Tree_Node +{ + const char *name; + Eina_List *color_classes; +}; + /*----------*/ struct _Edje_Program /* a conditional program to be run */ @@ -2360,6 +2370,7 @@ const char * _edje_text_font_get(const char *base, const char *new, Edje_Real_Part *_edje_real_part_get(const Edje *ed, const char *part); Edje_Real_Part *_edje_real_part_recursive_get(Edje **ed, const char *part); Edje_Color_Class *_edje_color_class_find(const Edje *ed, const char *color_class); +Edje_Color_Class *_edje_color_class_recursive_find(const Edje *ed, const char *color_class); void _edje_color_class_member_add(Edje *ed, const char *color_class); void _edje_color_class_member_del(Edje *ed, const char *color_class); void _edje_color_class_member_clean(Edje *ed); diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index 8dc51c361e..892022b96e 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -613,6 +613,39 @@ _edje_object_thaw(Eo *obj EINA_UNUSED, Edje *ed) return _edje_util_thaw(ed); } +static void +_edje_color_class_apply(const char *color_class, const char *parent) +{ + Eina_Hash *members; + Eina_Iterator *it; + Edje_Refcount *er; + Edje_Color_Tree_Node *ctn; + Eina_List *l, *ll; + char *name; + + members = eina_hash_find(_edje_color_class_member_hash, color_class); + if (!members) return; + it = eina_hash_iterator_data_new(members); + EINA_ITERATOR_FOREACH(it, er) + { + er->ed->dirty = EINA_TRUE; + er->ed->recalc_call = EINA_TRUE; +#ifdef EDJE_CALC_CACHE + er->ed->all_part_change = EINA_TRUE; +#endif + _edje_recalc(er->ed); + _edje_emit(er->ed, "color_class,set", parent); + + EINA_LIST_FOREACH(er->ed->file->color_tree, l, ctn) + { + if ((!strcmp(ctn->name, color_class)) && (ctn->color_classes)) + EINA_LIST_FOREACH(ctn->color_classes, ll, name) + _edje_color_class_apply(name, parent); + } + } + eina_iterator_free(it); +} + EAPI Eina_Bool edje_color_class_set(const char *color_class, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3) { @@ -671,20 +704,8 @@ edje_color_class_set(const char *color_class, int r, int g, int b, int a, int r2 cc->b3 = b3; cc->a3 = a3; - members = eina_hash_find(_edje_color_class_member_hash, color_class); - if (!members) return EINA_TRUE; - it = eina_hash_iterator_data_new(members); - EINA_ITERATOR_FOREACH(it, er) - { - er->ed->dirty = EINA_TRUE; - er->ed->recalc_call = EINA_TRUE; -#ifdef EDJE_CALC_CACHE - er->ed->all_part_change = EINA_TRUE; -#endif - _edje_recalc(er->ed); - _edje_emit(er->ed, "color_class,set", color_class); - } - eina_iterator_free(it); + _edje_color_class_apply(color_class, color_class); + return EINA_TRUE; } @@ -5761,6 +5782,50 @@ _edje_color_class_find(const Edje *ed, const char *color_class) return NULL; } +Edje_Color_Class * +_edje_color_class_recursive_find_helper(const Edje *ed, Eina_Hash *hash, const char *color_class) +{ + Edje_Color_Class *cc = NULL; + Edje_Color_Tree_Node *ctn = NULL; + const char *parent; + + cc = eina_hash_find(hash, color_class); + if (cc) return cc; + else + { + parent = color_class; + while ((ctn = eina_hash_find(ed->file->color_tree_hash, parent))) + { + parent = ctn->name; + cc = eina_hash_find(hash, parent); + if (cc) return cc; + } + } + return NULL; +} + +Edje_Color_Class * +_edje_color_class_recursive_find(const Edje *ed, const char *color_class) +{ + Edje_Color_Class *cc = NULL; + + if ((!ed) || (!color_class)) return NULL; + + /* first look through the object scope */ + cc = _edje_color_class_recursive_find_helper(ed, ed->color_classes, color_class); + if (cc) return cc; + + /* next look through the global scope */ + cc = _edje_color_class_recursive_find_helper(ed, _edje_color_class_hash, color_class); + if (cc) return cc; + + /* finally, look through the file scope */ + cc = _edje_color_class_recursive_find_helper(ed, ed->file->color_hash, color_class); + if (cc) return cc; + + return NULL; +} + void _edje_color_class_member_add(Edje *ed, const char *color_class) {