diff --git a/src/bin/edje/edje_cc.h b/src/bin/edje/edje_cc.h index 27338c3540..d7063ef466 100644 --- a/src/bin/edje/edje_cc.h +++ b/src/bin/edje/edje_cc.h @@ -270,6 +270,8 @@ int statement_handler_short_single_num(void); int nested_handler_num(void); int nested_handler_short_num(void); +void color_class_register(const char *name); + void reorder_parts(void); void source_edd(void); void source_fetch(void); @@ -348,6 +350,8 @@ extern Eina_List *color_tree_root; extern int beta; extern int no_warn_unused_images; +extern Eina_Hash *color_class_reg; + extern int had_quote; extern unsigned int max_open_files; diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c index 4377204b69..ac4be862a6 100644 --- a/src/bin/edje/edje_cc_handlers.c +++ b/src/bin/edje/edje_cc_handlers.c @@ -190,6 +190,8 @@ struct _Edje_Cc_Handlers_Hierarchy_Info /* Struct that keeps globals value to im }; typedef struct _Edje_Cc_Handlers_Hierarchy_Info Edje_Cc_Handlers_Hierarchy_Info; +static void color_class_register_color_tag(const char *tag); + static Eina_Array *part_hierarchy = NULL; /* stack parts,support nested parts */ static void edje_cc_handlers_hierarchy_set(Edje_Part *src); static Edje_Part *edje_cc_handlers_hierarchy_parent_get(void); @@ -1131,6 +1133,70 @@ New_Statement_Handler statement_handlers_short_single[] = {"collections.group.parts.part.description.inherit", st_collections_group_parts_part_description_inherit}, }; +void +color_class_register(const char *name) +{ + if (!color_class_reg) color_class_reg = eina_hash_string_superfast_new(NULL); + if (!color_class_reg) + { + ERR("Out of memory"); + exit(-1); + } + if (eina_hash_find(color_class_reg, name)) return; + eina_hash_add(color_class_reg, name, color_class_reg); +} + +static void +color_class_register_color_tag_span(const char *start, const char *end) +{ + const char *s; + char *ts; + + if (!start) return; + char *tmps = malloc(end - start + 1); + if (!tmps) + { + ERR("out of memory"); + exit(-1); + } + for (ts = tmps, s = start; s < end; s++, ts++) *ts = *s; + *ts = 0; + color_class_register(tmps); + free(tmps); +} + +static void +color_class_register_color_tag(const char *tag) +{ + // find in tag string "xxx=cc:yyy and pass to color_class_register() + const char *s, *cc_start = NULL, *cc_end = NULL; + + for (s = tag; *s; s++) + { + if (!cc_start) + { + if ((s[0] == '=') && (s[1] == 'c') && (s[2] == 'c') && (s[3] == ':')) + { + cc_end = NULL; + cc_start = s + 4; + s += 3; + } + } + else + { + if (isblank(s[0])) + { + cc_end = s; + color_class_register_color_tag_span(cc_start, cc_end); + cc_start = NULL; + cc_end = NULL; + } + } + } + if (cc_start && !cc_end) cc_end = s; + color_class_register_color_tag_span(cc_start, cc_end); +} + /** @edcsubsection{lazedc_external_params, * LazEDC Group.Parts.External.Desc.Params} */ @@ -3202,6 +3268,7 @@ st_styles_style_base(void) tag->key = mem_strdup("DEFAULT"); tag->value = parse_str(0); stl->tags = eina_list_append(stl->tags, tag); + color_class_register_color_tag(tag->value); } /** @@ -3228,6 +3295,7 @@ st_styles_style_tag(void) tag->key = parse_str(0); tag->value = parse_str(1); stl->tags = eina_list_append(stl->tags, tag); + color_class_register_color_tag(tag->value); } /** @edcsubsection{toplevel_text_classes, @@ -9084,6 +9152,7 @@ st_collections_group_parts_part_description_color_class(void) } current_desc->color_class = parse_str(0); + color_class_register(current_desc->color_class); } /** diff --git a/src/bin/edje/edje_cc_out.c b/src/bin/edje/edje_cc_out.c index e97a8ec005..5f53fa76b9 100644 --- a/src/bin/edje/edje_cc_out.c +++ b/src/bin/edje/edje_cc_out.c @@ -224,6 +224,7 @@ Eina_List *codes = NULL; Eina_List *code_lookups = NULL; Eina_List *aliases = NULL; Eina_List *color_tree_root = NULL; +Eina_Hash *color_class_reg = NULL; static Eet_Data_Descriptor *edd_edje_file = NULL; static Eet_Data_Descriptor *edd_edje_part_collection = NULL; @@ -2781,6 +2782,44 @@ data_thread_fontmap_end(void *data EINA_UNUSED, Ecore_Thread *thread EINA_UNUSED thread_end(0); } +static Eina_Bool +data_write_color_class_register_each_cb(const Eina_Hash *hash EINA_UNUSED, + const void *key, + void *data EINA_UNUSED, + void *fdata) +{ + Edje_Color_Class_Info *cc_info = fdata; + cc_info->colors = eina_list_append(cc_info->colors, + eina_stringshare_add(key)); + return EINA_TRUE; +} + +static void +data_write_color_class_register(Eet_File *ef) +{ + Edje_Color_Class_Info *cc_info; + const char *s; + + if (!color_class_reg) return; + cc_info = calloc(1, sizeof(Edje_Color_Class_Info)); + if (!cc_info) + { + ERR("Out of Memory"); + exit(-1); + } + eina_hash_foreach(color_class_reg, + data_write_color_class_register_each_cb, + cc_info); + + eet_data_write(ef, _edje_edd_edje_color_class_info, + "edje/color_class_info", cc_info, compress_mode); + + eina_hash_free(color_class_reg); + color_class_reg = NULL; + EINA_LIST_FREE(cc_info->colors, s) eina_stringshare_del(s); + free(cc_info); +} + void data_write(void) { @@ -2893,6 +2932,7 @@ data_write(void) data_thread_authors_end(ef, NULL); } } + data_write_color_class_register(ef); data_write_images(); data_image_sets_init(); INF("images: %3.5f", ecore_time_get() - t); t = ecore_time_get(); @@ -4458,6 +4498,7 @@ process_color_tree(char *s, const char *f_in, int ln) ctn = mem_alloc(SZ(Edje_Color_Tree_Node)); ctn->name = strdup(token[!id]); + color_class_register(ctn->name); ctn->color_classes = NULL; edje_file->color_tree = eina_list_append(edje_file->color_tree, ctn); diff --git a/src/lib/edje/Edje_Common.h b/src/lib/edje/Edje_Common.h index c94a2ff9ac..e03154e6ec 100644 --- a/src/lib/edje/Edje_Common.h +++ b/src/lib/edje/Edje_Common.h @@ -1807,6 +1807,37 @@ EAPI Eina_List *edje_mmap_collection_list(Eina_File *f); */ EAPI void edje_mmap_collection_list_free(Eina_List *lst); +/** + * @brief Returns a list of colorclasses used in this edje file + * @param f The mapped file + * + * @return A list of strings freed by edje_file_color_class_used_free() + * + * @since 1.26 + */ +EAPI Eina_List *edje_mmap_color_class_used_list(Eina_File *f); + +/** + * @brief Returns a list of colorclasses used in this edje file + * @param file The file path + * + * @return A list of strings freed by edje_file_color_class_used_free() + * + * @since 1.26 + */ +EAPI Eina_List *edje_file_color_class_used_list(const char *file); + +/** + * @brief Frees a list of color classes used + * @param The list + * + * This frees the list returned by edje_mmap_color_class_used_list() or + * edje_file_color_class_used_list() when you no longer need it. + * + * @since 1.26 + */ +EAPI void edje_file_color_class_used_free(Eina_List *lst); + /** * @brief Determines whether a group matching glob exists in an edje mapped file. * @param f The mapped file diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index 6a89fd9ca9..1ce628075f 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -2,6 +2,7 @@ EAPI Eet_Data_Descriptor * _edje_edd_edje_file = NULL; EAPI Eet_Data_Descriptor * _edje_edd_edje_part_collection = NULL; +EAPI Eet_Data_Descriptor * _edje_edd_edje_color_class_info = NULL; Eet_Data_Descriptor *_edje_edd_edje_string = NULL; Eet_Data_Descriptor *_edje_edd_edje_style = NULL; @@ -310,6 +311,7 @@ _edje_edd_shutdown(void) FREED(_edje_edd_edje_file); FREED(_edje_edd_edje_part_collection); + FREED(_edje_edd_edje_color_class_info); } #define EDJE_DEFINE_POINTER_TYPE(Type, Name) \ @@ -410,6 +412,11 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_image_directory, Edje_Image_Directory, "sets", sets, _edje_edd_edje_image_directory_set); EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_image_directory, Edje_Image_Directory, "vectors", vectors, _edje_edd_edje_vector_directory_entry); + /* collection directory */ + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Color_Class_Info); + _edje_edd_edje_color_class_info = eet_data_descriptor_file_new(&eddc); + EET_DATA_DESCRIPTOR_ADD_LIST_STRING(_edje_edd_edje_color_class_info, Edje_Color_Class_Info, "colors", colors); + /*MO*/ EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Mo); diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index acf0826b1d..1b9f025ebf 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -207,6 +207,62 @@ edje_mmap_collection_list_free(Eina_List *lst) edje_file_collection_list_free(lst); } +EAPI Eina_List * +edje_mmap_color_class_used_list(Eina_File *f) +{ + Eina_List *lst = NULL, *l; + Edje_File *edf; + int error_ret = 0; + const char *s; + + if (!f) return NULL; + edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL); + if (edf) + { + Edje_Color_Class_Info *cc_info; + + cc_info = eet_data_read(edf->ef, _edje_edd_edje_color_class_info, + "edje/color_class_info"); + if (cc_info) + { + EINA_LIST_FOREACH(cc_info->colors, l, s) + lst = eina_list_append(lst, eina_stringshare_add(s)); + eina_list_free(cc_info->colors); + free(cc_info); + } + _edje_cache_file_unref(edf); + } + + return lst; +} + +EAPI Eina_List * +edje_file_color_class_used_list(const char *file) +{ + Eina_File *f; + Eina_List *lst = NULL; + char *tmp; + + if ((!file) || (!*file)) return NULL; + tmp = eina_vpath_resolve(file); + f = eina_file_open(tmp, EINA_FALSE); + if (!f) goto err; + + lst = edje_mmap_collection_list(f); + + eina_file_close(f); // close matching open OK +err: + free(tmp); + return lst; +} + +EAPI void +edje_file_color_class_used_free(Eina_List *lst) +{ + eina_list_free(lst); +} + + EAPI Eina_Bool edje_mmap_group_exists(Eina_File *f, const char *glob) { diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 1d289123a7..d7f8ff6a3e 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -327,7 +327,7 @@ 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_Vector_Directory_Entry Edje_Vector_Directory_Entry; - +typedef struct _Edje_Color_Class_Info Edje_Color_Class_Info; typedef struct _Edje_Vibration_Sample Edje_Vibration_Sample; typedef struct _Edje_Vibration_Directory Edje_Vibration_Directory; @@ -656,7 +656,12 @@ struct _Edje_External_Directory_Entry /*----------*/ - +/*----------*/ +struct _Edje_Color_Class_Info +{ + Eina_List *colors; +}; +/*----------*/ /*----------*/ @@ -2334,6 +2339,7 @@ EAPI void _edje_edd_shutdown(void); EAPI extern Eet_Data_Descriptor *_edje_edd_edje_file; EAPI extern Eet_Data_Descriptor *_edje_edd_edje_part_collection; +EAPI extern Eet_Data_Descriptor *_edje_edd_edje_color_class_info; extern Eina_Inlist *_edje_edjes; diff --git a/src/lib/elementary/elm_theme.c b/src/lib/elementary/elm_theme.c index 7a40a4d7e9..123bc0f14e 100644 --- a/src/lib/elementary/elm_theme.c +++ b/src/lib/elementary/elm_theme.c @@ -521,6 +521,80 @@ _elm_theme_shutdown(void) } } + + + + +static Eina_List * +_elm_theme_file_color_class_list(Eina_List *list, + Eina_Inlist *handles) +{ + Eina_Stringshare *c; + Eina_List *ccl; + Eina_List *ll; + Elm_Theme_File *etf; + + EINA_INLIST_FOREACH(handles, etf) + { + ccl = edje_mmap_color_class_used_list(etf->handle); + EINA_LIST_FOREACH(ccl, ll, c) + { + list = eina_list_append(list, eina_stringshare_add(c)); + } + edje_file_color_class_used_free(ccl); + } + return list; +} + +static Eina_Bool +_elm_theme_color_class_list_hash_cb(const Eina_Hash *hash EINA_UNUSED, + const void *key, + void *data EINA_UNUSED, + void *fdata) +{ + Eina_List **list = fdata; + + *list = eina_list_append(*list, eina_stringshare_add(key)); + return EINA_TRUE; +} + +EAPI Eina_List * +elm_theme_color_class_list(Elm_Theme *th) +{ + Eina_List *list; + Eina_Hash *hash; + const char *s; + + if (!th) th = theme_default; + if (!th) return NULL; + + // go through all possible theme files and find collections that match + list = _elm_theme_file_color_class_list(NULL, th->overlay); + list = _elm_theme_file_color_class_list(list, th->themes); + list = _elm_theme_file_color_class_list(list, th->extension); + + hash = eina_hash_string_superfast_new(NULL); + EINA_LIST_FREE(list, s) + { + if (!eina_hash_find(hash, s)) eina_hash_add(hash, s, hash); + eina_stringshare_del(s); + } + eina_hash_foreach(hash, _elm_theme_color_class_list_hash_cb, &list); + eina_hash_free(hash); + + // sort the list nicely at the end + list = eina_list_sort(list, 0, EINA_COMPARE_CB(strcmp)); + return list; +} + +EAPI void +elm_theme_color_class_list_free(Eina_List *list) +{ + const char *s; + + EINA_LIST_FREE(list, s) eina_stringshare_del(s); +} + EAPI Elm_Theme * elm_theme_new(void) { diff --git a/src/lib/elementary/elm_theme.h b/src/lib/elementary/elm_theme.h index 7bf51d5b28..a5c55295da 100644 --- a/src/lib/elementary/elm_theme.h +++ b/src/lib/elementary/elm_theme.h @@ -78,6 +78,31 @@ */ typedef struct _Elm_Theme Elm_Theme; +/** + * Return a list of strings of color classes used in the given theme + * + * @param th The theme to get the reference from (NULL will be default) + * @return The list of color classes + * + * Free the returned list using elm_theme_color_class_list_free() when done. + * + * @ingroup Elm_Theme + * @sizne 1.26 + */ +EAPI Eina_List *elm_theme_color_class_list(Elm_Theme *th); + +/** + * Free list of color classes used in the themes + * + * @param list The list to free + * + * Free the returned list returned from elm_theme_color_class_list() + * + * @ingroup Elm_Theme + * @sizne 1.26 + */ +EAPI void elm_theme_color_class_list_free(Eina_List *list); + /** * Create a new specific theme *