From 15c300d5137b466b6dcda46572b170eff9335d4a Mon Sep 17 00:00:00 2001 From: Jee-Yong Um Date: Tue, 8 Dec 2015 12:15:48 +0900 Subject: [PATCH] edje: introduce size_class attribute Edje_Part can change its min or max size in code level with size_class. Differential Revision: https://phab.enlightenment.org/D3329 PS: Manual commit, arc refused to work... @feature Signed-off-by: Jean-Philippe Andre Change-Id: I423a88c3eccb2f2564597133b33dc417903cb102 --- src/bin/edje/edje_cc_handlers.c | 190 +++++++++++++++ src/bin/edje/edje_convert.c | 1 + src/bin/edje/edje_convert.h | 1 + src/bin/edje/edje_data_convert.c | 2 + src/lib/edje/Edje_Common.h | 101 ++++++++ src/lib/edje/edje_cache.c | 6 + src/lib/edje/edje_calc.c | 41 +++- src/lib/edje/edje_convert.c | 1 + src/lib/edje/edje_convert.h | 1 + src/lib/edje/edje_data.c | 14 ++ src/lib/edje/edje_load.c | 30 +++ src/lib/edje/edje_main.c | 6 + src/lib/edje/edje_object.eo | 46 ++++ src/lib/edje/edje_private.h | 22 ++ src/lib/edje/edje_smart.c | 10 + src/lib/edje/edje_util.c | 485 +++++++++++++++++++++++++++++++++++++++ 16 files changed, 947 insertions(+), 10 deletions(-) diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c index 6f76917..a2c0735 100644 --- a/src/bin/edje/edje_cc_handlers.c +++ b/src/bin/edje/edje_cc_handlers.c @@ -223,6 +223,11 @@ static void st_color_class_color2(void); static void st_color_class_color3(void); static void st_color_class_desc(void); +static void ob_size_class(void); +static void st_size_class_name(void); +static void st_size_class_min(void); +static void st_size_class_max(void); + static void ob_filters_filter(void); static void ob_filters_filter_script(void); static void st_filters_filter_file(void); @@ -349,6 +354,7 @@ static void st_collections_group_parts_part_description_rel2_to(void); static void st_collections_group_parts_part_description_rel2_to_x(void); static void st_collections_group_parts_part_description_rel2_to_y(void); static void st_collections_group_parts_part_description_clip_to_id(void); +static void st_collections_group_parts_part_description_size_class(void); static void st_collections_group_parts_part_description_image_normal(void); static void st_collections_group_parts_part_description_image_tween(void); static void st_collections_group_parts_part_description_image_border(void); @@ -560,6 +566,11 @@ static void st_collections_plugins_plugin_param(void); {PREFIX"color_classes.color_class.description", st_color_class_desc}, /* dup */ \ {PREFIX"color_classes.color_class.desc", st_color_class_desc}, /* dup */ +#define SIZE_CLASS_STATEMENTS(PREFIX) \ + {PREFIX"size_classes.size_class.name", st_size_class_name}, /* dup */ \ + {PREFIX"size_classes.size_class.min", st_size_class_min}, /* dup */ \ + {PREFIX"size_classes.size_class.max", st_size_class_max}, /* dup */ + #define PROGRAM_SEQUENCE(PREFIX, NAME, FN) \ {PREFIX".program."NAME, FN}, /* dup */ \ {PREFIX".program.sequence."NAME, FN}, /* dup */ @@ -662,6 +673,7 @@ New_Statement_Handler statement_handlers[] = {"externals.external", st_externals_external}, IMAGE_STATEMENTS("") FONT_STYLE_CC_STATEMENTS("") + SIZE_CLASS_STATEMENTS("") {"data.item", st_data_item}, {"data.file", st_data_file}, FILTERS_STATEMENTS("") @@ -670,6 +682,7 @@ New_Statement_Handler statement_handlers[] = IMAGE_SET_STATEMENTS("collections") {"collections.font", st_fonts_font}, /* dup */ FONT_STYLE_CC_STATEMENTS("collections.") + SIZE_CLASS_STATEMENTS("collections.") {"collections.base_scale", st_collections_base_scale}, // TIZEN_ONLY(20150110): Add plugins keyword. #ifdef PLUGIN @@ -723,11 +736,13 @@ New_Statement_Handler statement_handlers[] = {"collections.group.models.model", st_models_model}, {"collections.group.font", st_fonts_font}, /* dup */ FONT_STYLE_CC_STATEMENTS("collections.group.") + SIZE_CLASS_STATEMENTS("collections.group.") {"collections.group.parts.alias", st_collections_group_parts_alias }, IMAGE_SET_STATEMENTS("collections.group.parts") IMAGE_STATEMENTS("collections.group.parts.") {"collections.group.parts.font", st_fonts_font}, /* dup */ FONT_STYLE_CC_STATEMENTS("collections.group.parts.") + SIZE_CLASS_STATEMENTS("collections.group.parts.") {"collections.group.parts.target_group", st_collections_group_target_group}, /* dup */ {"collections.group.parts.part.name", st_collections_group_parts_part_name}, {"collections.group.parts.part.target_group", st_collections_group_target_group}, /* dup */ @@ -771,6 +786,7 @@ New_Statement_Handler statement_handlers[] = IMAGE_STATEMENTS("collections.group.parts.part.") {"collections.group.parts.part.font", st_fonts_font}, /* dup */ FONT_STYLE_CC_STATEMENTS("collections.group.parts.part.") + SIZE_CLASS_STATEMENTS("collections.group.parts.part.") {"collections.group.parts.part.box.items.item.type", st_collections_group_parts_part_box_items_item_type}, {"collections.group.parts.part.box.items.item.name", st_collections_group_parts_part_box_items_item_name}, {"collections.group.parts.part.box.items.item.source", st_collections_group_parts_part_box_items_item_source}, @@ -831,6 +847,7 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.description.rel2.to_x", st_collections_group_parts_part_description_rel2_to_x}, {"collections.group.parts.part.description.rel2.to_y", st_collections_group_parts_part_description_rel2_to_y}, {"collections.group.parts.part.description.clip_to", st_collections_group_parts_part_description_clip_to_id}, + {"collections.group.parts.part.description.size_class", st_collections_group_parts_part_description_size_class}, {"collections.group.parts.part.description.image.normal", st_collections_group_parts_part_description_image_normal}, {"collections.group.parts.part.description.image.tween", st_collections_group_parts_part_description_image_tween}, IMAGE_SET_STATEMENTS("collections.group.parts.part.description.image") @@ -952,6 +969,7 @@ New_Statement_Handler statement_handlers[] = 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.") + SIZE_CLASS_STATEMENTS("collections.group.parts.part.description.") #ifdef HAVE_EPHYSICS {"collections.group.physics.world.gravity", st_collections_group_physics_world_gravity}, {"collections.group.physics.world.rate", st_collections_group_physics_world_rate}, @@ -1162,6 +1180,8 @@ New_Object_Handler object_handlers[] = {"styles.style", ob_styles_style}, {"color_classes", NULL}, {"color_classes.color_class", ob_color_class}, + {"size_classes", NULL}, + {"size_classes.size_class", ob_size_class}, {"spectra", NULL}, {"filters", NULL}, {"filters.filter", ob_filters_filter}, @@ -1178,6 +1198,8 @@ New_Object_Handler object_handlers[] = {"collections.styles.style", ob_styles_style}, /* dup */ {"collections.color_classes", NULL}, /* dup */ {"collections.color_classes.color_class", ob_color_class}, /* dup */ + {"collections.size_classes", NULL}, /* dup */ + {"collections.size_classes.size_class", ob_size_class}, /* dup */ // TIZEN_ONLY(20150110): Add plugins keyword. #ifdef PLUGIN {"collections.plugins", NULL}, /* dup */ @@ -1218,6 +1240,8 @@ New_Object_Handler object_handlers[] = {"collections.group.styles.style", ob_styles_style}, /* dup */ {"collections.group.color_classes", NULL}, /* dup */ {"collections.group.color_classes.color_class", ob_color_class}, /* dup */ + {"collections.group.size_classes", NULL}, /* dup */ + {"collections.group.size_classes.size_class", ob_size_class}, /* dup */ {"collections.group.filters", NULL}, {"collections.group.filters.filter", ob_filters_filter}, /* dup */ {"collections.group.filters.filter.script", ob_filters_filter_script}, /* dup */ @@ -1232,6 +1256,8 @@ New_Object_Handler object_handlers[] = {"collections.group.parts.styles.style", ob_styles_style}, /* dup */ {"collections.group.parts.color_classes", NULL}, /* dup */ {"collections.group.parts.color_classes.color_class", ob_color_class}, /* dup */ + {"collections.group.parts.size_classes", NULL}, /* dup */ + {"collections.group.parts.size_classes.size_class", ob_size_class}, /* dup */ {"collections.group.parts.part", ob_collections_group_parts_part}, {"collections.group.parts.part.dragable", NULL}, {"collections.group.parts.part.set", ob_images_set}, /* dup */ @@ -1244,6 +1270,8 @@ New_Object_Handler object_handlers[] = {"collections.group.parts.part.styles.style", ob_styles_style}, /* dup */ {"collections.group.parts.part.color_classes", NULL}, /* dup */ {"collections.group.parts.part.color_classes.color_class", ob_color_class}, /* dup */ + {"collections.group.parts.part.size_classes", NULL}, /* dup */ + {"collections.group.parts.part.size_classes.size_class", ob_size_class}, /* dup */ {"collections.group.parts.part.box", NULL}, {"collections.group.parts.part.box.items", NULL}, {"collections.group.parts.part.box.items.item", ob_collections_group_parts_part_box_items_item}, @@ -1292,6 +1320,8 @@ New_Object_Handler object_handlers[] = {"collections.group.parts.part.description.params", NULL}, {"collections.group.parts.part.description.color_classes", NULL}, /* dup */ {"collections.group.parts.part.description.color_classes.color_class", ob_color_class}, /* dup */ + {"collections.group.parts.part.description.size_classes", NULL}, /* dup */ + {"collections.group.parts.part.description.size_classes.size_class", ob_size_class}, /* dup */ #ifdef HAVE_EPHYSICS {"collections.group.physics", NULL}, {"collections.group.physics.world", NULL}, @@ -2910,6 +2940,137 @@ st_styles_style_tag(void) stl->tags = eina_list_append(stl->tags, tag); } +/** @edcsubsection{toplevel_size_classes, + * Size Classes} */ + +/** + @page edcref + @block + size_classes + @context + size_classes { + size_class { + name: "sizeclassname"; + min: width height; + max: width height; + } + .. + } + @description + The "size_classes" block contains a list of one or more "size_class" + blocks. Each "size_class" allows the designer to name an arbitrary + group of size to be used in the theme, the application can use that + name to alter the min and max size values at runtime. + @endblock +*/ +static void +ob_size_class(void) +{ + Edje_Size_Class *sc; + + sc = mem_alloc(SZ(Edje_Size_Class)); + edje_file->size_classes = eina_list_append(edje_file->size_classes, sc); + + sc->minw = 0; + sc->minh = 0; + sc->maxw = -1; + sc->maxh = -1; +} + +static void +_size_class_name(char *name) +{ + Edje_Size_Class *sc, *tsc; + Eina_List *l; + + sc = eina_list_data_get(eina_list_last(edje_file->size_classes)); + sc->name = name; + EINA_LIST_FOREACH(edje_file->size_classes, l, tsc) + { + if ((sc != tsc) && (!strcmp(sc->name, tsc->name))) + { + ERR("parse error %s:%i. There is already a size class named \"%s\"", + file_in, line - 1, sc->name); + exit(-1); + } + } +} + +/** + @page edcref + + @property + name + @parameters + [size class name] + @effect + Sets the name for the size class, used as reference by both the theme + and the application. + @endproperty +*/ +static void +st_size_class_name(void) +{ + Edje_Size_Class *sc, *tsc; + Eina_List *l; + + sc = eina_list_data_get(eina_list_last(edje_file->size_classes)); + sc->name = parse_str(0); + EINA_LIST_FOREACH(edje_file->size_classes, l, tsc) + { + if ((sc != tsc) && (!strcmp(sc->name, tsc->name))) + { + ERR("parse error %s:%i. There is already a size class named \"%s\"", + file_in, line - 1, sc->name); + exit(-1); + } + } +} + +/** + @page edcref + @property + min + @parameters + [width] [height] + @effect + The minimum size. + @endproperty +*/ +static void +st_size_class_min(void) +{ + Edje_Size_Class *sc; + + check_arg_count(2); + + sc = eina_list_data_get(eina_list_last(edje_file->size_classes)); + sc->minw = parse_int_range(0, 0, 0x7fffffff); + sc->minh = parse_int_range(1, 0, 0x7fffffff); +} + +/** + @page edcref + @property + max + @parameters + [width] [height] + @effect + The maximum size. + @endproperty +*/ +static void +st_size_class_max(void) +{ + Edje_Size_Class *sc; + + check_arg_count(2); + + sc = eina_list_data_get(eina_list_last(edje_file->size_classes)); + sc->maxw = parse_int_range(0, -1, 0x7fffffff); + sc->maxh = parse_int_range(1, -1, 0x7fffffff); +} + /** @edcsection{collections,Collections Blocks} */ /** @edcsubsection{collections, @@ -7186,6 +7347,7 @@ ob_collections_group_parts_part_description(void) ed->fixed.h = 0; ed->max.w = -1; ed->max.h = -1; + ed->size_class = NULL; ed->rel1.relative_x = FROM_DOUBLE(0.0); ed->rel1.relative_y = FROM_DOUBLE(0.0); ed->rel1.offset_x = 0; @@ -7367,6 +7529,7 @@ st_collections_group_parts_part_description_inherit(void) */ #define STRDUP(x) x ? strdup(x) : NULL + ed->size_class = STRDUP(ed->size_class); ed->color_class = STRDUP(ed->color_class); ed->map.colors = _copied_map_colors_get(parent); @@ -7933,6 +8096,26 @@ st_collections_group_parts_part_description_max(void) } /** + @page edcref + @property + size_class + @parameters + [size class name] + @effect + The part will have the min and max size defined in the size class. + "min" and "max" property in description can be overridden by the size class + at runtime. + @endproperty +*/ +static void +st_collections_group_parts_part_description_size_class(void) +{ + check_arg_count(1); + + current_desc->size_class = parse_str(0); +} + +/** @page edcref @property step @@ -14400,6 +14583,13 @@ edje_cc_handlers_wildcard(void) stack_pop_quick(EINA_FALSE, EINA_FALSE); return EINA_TRUE; } + if (edje_file->size_classes && (!strcmp(last, "size_class"))) + { + if (!had_quote) return EINA_FALSE; + _size_class_name(token); + stack_pop_quick(EINA_FALSE, EINA_FALSE); + return EINA_TRUE; + } return EINA_FALSE; } diff --git a/src/bin/edje/edje_convert.c b/src/bin/edje/edje_convert.c index 1aff944..697d035 100644 --- a/src/bin/edje/edje_convert.c +++ b/src/bin/edje/edje_convert.c @@ -158,6 +158,7 @@ _edje_file_convert(Eet_File *ef, Old_Edje_File *oedf) edf->styles = oedf->styles; edf->color_classes = oedf->color_classes; + edf->size_classes = oedf->size_classes; edf->version = EDJE_FILE_VERSION; edf->feature_ver = oedf->feature_ver; edf->compiler = oedf->compiler; diff --git a/src/bin/edje/edje_convert.h b/src/bin/edje/edje_convert.h index fe2bff1..8c11333 100644 --- a/src/bin/edje/edje_convert.h +++ b/src/bin/edje/edje_convert.h @@ -49,6 +49,7 @@ struct _Old_Edje_File Eina_List *data; Eina_List *styles; Eina_List *color_classes; + Eina_List *size_classes; const char *compiler; int version; diff --git a/src/bin/edje/edje_data_convert.c b/src/bin/edje/edje_data_convert.c index bea6eeb..86ff7f5 100644 --- a/src/bin/edje/edje_data_convert.c +++ b/src/bin/edje/edje_data_convert.c @@ -194,6 +194,7 @@ _edje_edd_old_init(void) EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_old_edje_file, Old_Edje_File, "data", data, _edje_edd_old_edje_data); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_old_edje_file, Old_Edje_File, "styles", styles, _edje_edd_old_edje_style); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_old_edje_file, Old_Edje_File, "color_classes", color_classes, _edje_edd_old_edje_color_class); + EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_old_edje_file, Old_Edje_File, "size_classes", size_classes, _edje_edd_old_edje_size_class); /* parts & programs - loaded induvidually */ EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Program_Target); @@ -357,6 +358,7 @@ _edje_edd_old_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_old_edje_part_description, Old_Edje_Part_Description, "map.backcull", common.map.backcull, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_old_edje_part_description, Old_Edje_Part_Description, "persp.zplane", common.persp.zplane, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_old_edje_part_description, Old_Edje_Part_Description, "persp.focal", common.persp.focal, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_old_edje_part_description, Old_Edje_Part_Description, "size_class", common.size_class, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_old_edje_part_description, Old_Edje_Part_Description, "external_params", external_params, _edje_edd_old_edje_external_param); EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Pack_Element); diff --git a/src/lib/edje/Edje_Common.h b/src/lib/edje/Edje_Common.h index 96fac12..646ea87 100644 --- a/src/lib/edje/Edje_Common.h +++ b/src/lib/edje/Edje_Common.h @@ -1753,6 +1753,107 @@ EAPI Eina_List *edje_text_class_list (void); */ /** + * @defgroup Edje_Object_Size_Class Edje Class: Size + * + * @brief Functions that deal with Size Classes + * + * Sometimes we want to change the size of two or more parts equally and + * that's when we use size classes. + * + * If one or more parts are assigned with a size class, when we set attributes + * (minw etc.) to this class will update all these parts with the new attributes. + * Setting values to a size class at a process level will affect + * all parts with that size class, while at object level will affect only + * the parts inside an specified object. + * + * @ingroup Edje_Object_Group + * + * @{ + */ + +/** + * @brief Set the Edje size class. + * + * @param size_class The size class name + * @param minw The min width + * @param minh The min height + * @param maxw The max width + * @param maxh The max height + * + * @return @c EINA_TRUE, on success or @c EINA_FALSE, on error + * + * This function updates all Edje members at the process level which + * belong to this size class with the new min and max attributes. + * + * @see edje_size_class_get(). + * + */ +EAPI Eina_Bool edje_size_class_set (const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh); + +/** + * @brief Get the Edje size class. + * + * @param size_class The size class name + * @param minw The min width + * @param minh The min height + * @param maxw The max width + * @param maxh The max height + * + * @return @c EINA_TRUE, on success or @c EINA_FALSE, on error + * + * This function gets the min and max size from the specified Edje + * size class. + * + */ +EAPI Eina_Bool edje_size_class_get (const char *size_class, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh); + +/** + * @brief Delete the size class. + * + * @param size_class The size class name + * + * This function deletes any values at the process level for the + * specified size class. + * + */ +EAPI void edje_size_class_del (const char *size_class); + +/** + * @brief List size classes. + * + * @return A list of size class names (strings). These strings are + * stringshares and the list must be eina_stringshare_del()'ed by the caller. + * + * This function lists all size classes known about by the current + * process. + * + */ +EAPI Eina_List *edje_size_class_list (void); + +/** + * @brief Iterate over all active classes of an application. + * + * @return an iterator of Edje_Size_Class of the currently active size class + * + * This function only iterates over the Edje_Size_Class in use by + * an application. + * + */ +EAPI Eina_Iterator *edje_size_class_active_iterator_new(void); + +/** + * @brief Iterate over all size classes provided by an Edje file. + * + * @return an iterator of Edje_Size_Class provided by the Edje file. + * + */ +EAPI Eina_Iterator *edje_mmap_size_class_iterator_new(Eina_File *f); + +/** + * @} + */ + +/** * @defgroup Edje_Object_File Edje Object File * * @brief Functions to deals with EDJ files. diff --git a/src/lib/edje/edje_cache.c b/src/lib/edje/edje_cache.c index 1724b32..e0c5baf 100644 --- a/src/lib/edje/edje_cache.c +++ b/src/lib/edje/edje_cache.c @@ -264,6 +264,7 @@ static Edje_File * _edje_file_open(const Eina_File *f, int *error_ret, time_t mtime) { Edje_Color_Class *cc; + Edje_Size_Class *sc; Edje_File *edf; Eina_List *l; Eet_File *ef; @@ -320,6 +321,11 @@ _edje_file_open(const Eina_File *f, int *error_ret, time_t mtime) if (cc->name) eina_hash_direct_add(edf->color_hash, cc->name, cc); + edf->size_hash = eina_hash_string_small_new(NULL); + EINA_LIST_FOREACH(edf->size_classes, l, sc) + if (sc->name) + eina_hash_direct_add(edf->size_hash, sc->name, sc); + return edf; } diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index caaede4..ddbebff 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -2239,7 +2239,28 @@ _edje_part_recalc_single_min_max(FLOAT_T sc, int *minw, int *minh, int *maxw, int *maxh) { - *minw = desc->min.w; + Edje_Size_Class *size_class = NULL; + Evas_Coord mnw, mnh, mxw, mxh; + + if (desc->size_class) + size_class = _edje_size_class_find(ed, desc->size_class); + + if (size_class) + { + mnw = size_class->minw; + mnh = size_class->minh; + mxw = size_class->maxw; + mxh = size_class->maxh; + } + else + { + mnw = desc->min.w; + mnh = desc->min.h; + mxw = desc->max.w; + mxh = desc->max.h; + } + + *minw = mnw; if (ep->part->scale) *minw = TO_INT(SCALE(sc, *minw)); if ((ep->type == EDJE_RP_TYPE_SWALLOW) && (ep->typedata.swallow)) @@ -2264,7 +2285,7 @@ _edje_part_recalc_single_min_max(FLOAT_T sc, if ((ep->typedata.swallow->swallow_params.max.w <= 0) || (ep->typedata.swallow->swallow_params.max.w == EDJE_INF_MAX_W)) { - *maxw = desc->max.w; + *maxw = mxw; if (*maxw > 0) { if (ep->part->scale) *maxw = TO_INT(SCALE(sc, *maxw)); @@ -2273,11 +2294,11 @@ _edje_part_recalc_single_min_max(FLOAT_T sc, } else { - if (desc->max.w <= 0) + if (mxw <= 0) *maxw = ep->typedata.swallow->swallow_params.max.w; else { - *maxw = desc->max.w; + *maxw = mxw; if (*maxw > 0) { if (ep->part->scale) *maxw = TO_INT(SCALE(sc, *maxw)); @@ -2290,7 +2311,7 @@ _edje_part_recalc_single_min_max(FLOAT_T sc, } else { - *maxw = desc->max.w; + *maxw = mxw; if (*maxw > 0) { if (ep->part->scale) *maxw = TO_INT(SCALE(sc, *maxw)); @@ -2304,7 +2325,7 @@ _edje_part_recalc_single_min_max(FLOAT_T sc, if (*maxw < *minw) *maxw = *minw; } - *minh = desc->min.h; + *minh = mnh; if (ep->part->scale) *minh = TO_INT(SCALE(sc, *minh)); if ((ep->type == EDJE_RP_TYPE_SWALLOW) && (ep->typedata.swallow)) @@ -2329,7 +2350,7 @@ _edje_part_recalc_single_min_max(FLOAT_T sc, if ((ep->typedata.swallow->swallow_params.max.h <= 0) || (ep->typedata.swallow->swallow_params.max.h == EDJE_INF_MAX_H)) { - *maxh = desc->max.h; + *maxh = mxh; if (*maxh > 0) { if (ep->part->scale) *maxh = TO_INT(SCALE(sc, *maxh)); @@ -2338,11 +2359,11 @@ _edje_part_recalc_single_min_max(FLOAT_T sc, } else { - if (desc->max.h <= 0) + if (mxh <= 0) *maxh = ep->typedata.swallow->swallow_params.max.h; else { - *maxh = desc->max.h; + *maxh = mxh; if (*maxh > 0) { if (ep->part->scale) *maxh = TO_INT(SCALE(sc, *maxh)); @@ -2355,7 +2376,7 @@ _edje_part_recalc_single_min_max(FLOAT_T sc, } else { - *maxh = desc->max.h; + *maxh = mxh; if (*maxh > 0) { if (ep->part->scale) *maxh = TO_INT(SCALE(sc, *maxh)); diff --git a/src/lib/edje/edje_convert.c b/src/lib/edje/edje_convert.c index a491fd3..3f2b2c7 100644 --- a/src/lib/edje/edje_convert.c +++ b/src/lib/edje/edje_convert.c @@ -212,6 +212,7 @@ _edje_file_convert(Eet_File *file, Old_Edje_File *oedf) edf->oef = oedf; edf->styles = oedf->styles; edf->color_classes = oedf->color_classes; + edf->size_classes = oedf->size_classes; edf->version = oedf->version; edf->feature_ver = oedf->feature_ver; edf->compiler = oedf->compiler; diff --git a/src/lib/edje/edje_convert.h b/src/lib/edje/edje_convert.h index e387e26..da1b782 100644 --- a/src/lib/edje/edje_convert.h +++ b/src/lib/edje/edje_convert.h @@ -67,6 +67,7 @@ struct _Old_Edje_File Eina_List *data; /**< list of Edje_Data */ Eina_List *styles; /**< list of Edje_Style */ Eina_List *color_classes; /**< list of Edje_Color_Class */ + Eina_List *size_classes; /**< list of Edje_Size_Class */ const char *compiler; /**< compiler name */ int version; /**< Edje version */ diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index f9ef23d..9a38dee 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -12,6 +12,7 @@ Eet_Data_Descriptor *_edje_edd_edje_plugin = 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_class = NULL; +Eet_Data_Descriptor *_edje_edd_edje_size_class = NULL; Eet_Data_Descriptor *_edje_edd_edje_external_directory = NULL; Eet_Data_Descriptor *_edje_edd_edje_external_directory_entry = NULL; Eet_Data_Descriptor *_edje_edd_edje_font_directory_entry = NULL; @@ -250,6 +251,7 @@ _edje_edd_shutdown(void) FREED(_edje_edd_edje_style); FREED(_edje_edd_edje_style_tag); FREED(_edje_edd_edje_color_class); + FREED(_edje_edd_edje_size_class); FREED(_edje_edd_edje_external_directory); FREED(_edje_edd_edje_external_directory_entry); FREED(_edje_edd_edje_font_directory_entry); @@ -570,6 +572,15 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_color_class, Edje_Color_Class, "a3", a3, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_color_class, Edje_Color_Class, "desc", desc, EET_T_STRING); + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Size_Class); + _edje_edd_edje_size_class = + eet_data_descriptor_file_new(&eddc); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_size_class, Edje_Size_Class, "name", name, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_size_class, Edje_Size_Class, "minw", minw, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_size_class, Edje_Size_Class, "minh", minh, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_size_class, Edje_Size_Class, "maxw", maxw, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_size_class, Edje_Size_Class, "maxh", maxh, EET_T_INT); + /* evas filters */ EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Spec_Filter_Data); _edje_edd_edje_part_description_filter_data = eet_data_descriptor_file_new(&eddc); @@ -600,6 +611,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_classes", color_classes, _edje_edd_edje_color_class); + EET_DATA_DESCRIPTOR_ADD_LIST(_edje_edd_edje_file, Edje_File, "size_classes", size_classes, _edje_edd_edje_size_class); EET_DATA_DESCRIPTOR_ADD_HASH(_edje_edd_edje_file, Edje_File, "data", data, _edje_edd_edje_string); EET_DATA_DESCRIPTOR_ADD_HASH(_edje_edd_edje_file, Edje_File, "fonts", fonts, _edje_edd_edje_font_directory_entry); EET_DATA_DESCRIPTOR_ADD_HASH(_edje_edd_edje_file, Edje_File, "collection", collection, _edje_edd_edje_part_collection_directory_entry); @@ -743,6 +755,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "rel2.id_x", rel2.id_x, EET_T_INT); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "rel2.id_y", rel2.id_y, EET_T_INT); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "clip_to_id", clip_to_id, EET_T_INT); \ + EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "size_class", size_class, EET_T_STRING); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "color_class", color_class, EET_T_STRING); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "color.r", color.r, EET_T_UCHAR); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "color.g", color.g, EET_T_UCHAR); \ @@ -834,6 +847,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "rel2.id_x", Dec.rel2.id_x, EET_T_INT); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "rel2.id_y", Dec.rel2.id_y, EET_T_INT); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "clip_to_id", Dec.clip_to_id, EET_T_INT); \ + EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "size_class", Dec.size_class, EET_T_STRING); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "color_class", Dec.color_class, EET_T_STRING); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "color.r", Dec.color.r, EET_T_UCHAR); \ EET_DATA_DESCRIPTOR_ADD_BASIC(Edd, Type, "color.g", Dec.color.g, EET_T_UCHAR); \ diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index d62979b..35125b7 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -610,6 +610,28 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch _edje_color_class_member_add(ed, desc->color_class); } } + /* sizeclass stuff */ + for (i = 0; i < ed->collection->parts_count; ++i) + { + Edje_Part *ep; + unsigned int k; + + ep = ed->collection->parts[i]; + + /* Register any size classes in this parts descriptions. */ + if ((ep->default_desc) && (ep->default_desc->size_class)) + _edje_size_class_member_add(ed, ep->default_desc->size_class); + + for (k = 0; k < ep->other.desc_count; k++) + { + Edje_Part_Description_Common *desc; + + desc = ep->other.desc[k]; + + if (desc->size_class) + _edje_size_class_member_add(ed, desc->size_class); + } + } /* build real parts */ for (n = 0; n < ed->collection->parts_count; n++) { @@ -1705,6 +1727,7 @@ void _edje_file_free(Edje_File *edf) { Edje_Color_Class *ecc; + Edje_Size_Class *esc; #define HASH_FREE(Hash) \ if (Hash) eina_hash_free(Hash); \ @@ -1820,6 +1843,13 @@ _edje_file_free(Edje_File *edf) free(ecc); } + eina_hash_free(edf->size_hash); + EINA_LIST_FREE(edf->size_classes, esc) + { + if (edf->free_strings && esc->name) eina_stringshare_del(esc->name); + free(esc); + } + if (edf->collection_patterns) edje_match_patterns_free(edf->collection_patterns); if (edf->path) eina_stringshare_del(edf->path); if (edf->free_strings && edf->compiler) eina_stringshare_del(edf->compiler); diff --git a/src/lib/edje/edje_main.c b/src/lib/edje/edje_main.c index 80e0708..97259c8 100644 --- a/src/lib/edje/edje_main.c +++ b/src/lib/edje/edje_main.c @@ -166,6 +166,8 @@ shutdown_all: _edje_box_shutdown(); _edje_text_class_members_free(); _edje_text_class_hash_free(); + _edje_size_class_members_free(); + _edje_size_class_hash_free(); _edje_edd_shutdown(); // TIZEN_ONLY(20160313): get cache directory from XDG_CACHE_HOME env var if app doesn't want to use efreet. #if 1 @@ -222,6 +224,8 @@ _edje_shutdown_core(void) _edje_box_shutdown(); _edje_text_class_members_free(); _edje_text_class_hash_free(); + _edje_size_class_members_free(); + _edje_size_class_hash_free(); _edje_edd_shutdown(); eina_cow_del(_edje_calc_params_map_cow); @@ -317,6 +321,7 @@ _edje_del(Edje *ed) if (tc->font) eina_stringshare_del(tc->font); free(tc); } + eina_hash_free(ed->size_classes); EINA_LIST_FREE(ed->text_insert_filter_callbacks, cb) { eina_stringshare_del(cb->part); @@ -330,6 +335,7 @@ _edje_del(Edje *ed) _edje_color_class_member_clean(ed); _edje_text_class_members_clean(ed); + _edje_size_class_members_clean(ed); } void diff --git a/src/lib/edje/edje_object.eo b/src/lib/edje/edje_object.eo index a1a0aaa..c1e5661 100644 --- a/src/lib/edje/edje_object.eo +++ b/src/lib/edje/edje_object.eo @@ -2571,6 +2571,52 @@ class Edje.Object (Evas.Smart_Clipped, Efl.File) @since 1.17.0]] return: bool; [[$true, on success or $false, on error]] } + @property size_class { + set { + [[Sets the object size class. + + This function sets the min and max values for an object level size + class. This will make all edje parts in the specified object that + have the specified size class update their min and max size with given values. + + @since 1.17]] + return: bool; [[$true, on success or $false, on error]] + } + get { + [[Gets the object size class. + + This function gets the min and max values for an object level size + class. These values will only be valid until the size class is changed + or the edje object is deleted. + + @since 1.17]] + return: bool; [[$true, on success or $false, on error]] + } + keys { + size_class: const(char)*; [[The size class name]] + } + values { + minw: int; [[The min width]] + minh: int; [[The min height]] + maxw: int; [[The max width]] + maxh: int; [[The max height]] + } + } + size_class_del { + [[Delete the object size class. + + This function deletes any values at the object level for the + specified object and size class. + + Deleting the size class will revert it to the values + defined by edje_size_class_set() or the color class + defined in the theme file. + + @since 1.17]] + params { + @in size_class: const(char)*; + } + } part_drag_step { [[Steps the dragable x,y steps. diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 20e34dd..e0da59f 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -395,6 +395,7 @@ typedef struct _Edje_Calc_Params_Physics Edje_Calc_Params_Physics; typedef struct _Edje_Pending_Program Edje_Pending_Program; typedef struct _Edje_Text_Style Edje_Text_Style; typedef struct _Edje_Text_Class Edje_Text_Class; +typedef struct _Edje_Size_Class Edje_Size_Class; typedef struct _Edje_Var Edje_Var; typedef struct _Edje_Var_Int Edje_Var_Int; typedef struct _Edje_Var_Float Edje_Var_Float; @@ -558,6 +559,9 @@ struct _Edje_File Eina_List *color_classes; Eina_Hash *color_hash; + Eina_List *size_classes; + Eina_Hash *size_hash; + int references; const char *compiler; int version; @@ -1245,6 +1249,8 @@ struct _Edje_Part_Description_Common int clip_to_id; /* state clip override @since 1.15 */ + const char *size_class; + struct { FLOAT_T relative_x; FLOAT_T relative_y; @@ -1648,6 +1654,7 @@ struct _Edje Eina_List *pending_actions; Eina_Hash *color_classes; Eina_List *text_classes; + Eina_Hash *size_classes; /* variable pool for Edje Embryo scripts */ Edje_Var_Pool *var_pool; /* for faster lookups to avoid nth list walks */ @@ -2056,6 +2063,15 @@ struct _Edje_Text_Class Evas_Font_Size size; }; +struct _Edje_Size_Class +{ + Eina_Stringshare *name; + Evas_Coord minw; + Evas_Coord minh; + Evas_Coord maxw; + Evas_Coord maxh; +}; + struct _Edje_Var_Int { int v; @@ -2455,6 +2471,12 @@ void _edje_text_class_member_del(Edje *ed, const char *text_class); void _edje_text_class_members_free(void); void _edje_text_class_hash_free(void); void _edje_text_class_members_clean(Edje *ed); +Edje_Size_Class *_edje_size_class_find(Edje *ed, const char *size_class); +void _edje_size_class_member_add(Edje *ed, const char *size_class); +void _edje_size_class_member_del(Edje *ed, const char *size_class); +void _edje_size_class_members_free(void); +void _edje_size_class_hash_free(void); +void _edje_size_class_members_clean(Edje *ed); Edje *_edje_fetch(const Evas_Object *obj) EINA_PURE; int _edje_util_freeze(Edje *ed); int _edje_util_thaw(Edje *ed); diff --git a/src/lib/edje/edje_smart.c b/src/lib/edje/edje_smart.c index 59e4af9..50f8b52 100644 --- a/src/lib/edje/edje_smart.c +++ b/src/lib/edje/edje_smart.c @@ -73,6 +73,15 @@ _edje_color_class_free(void *data) free(cc); } +static void +_edje_size_class_free(void *data) +{ + Edje_Size_Class *sc = data; + + if (sc->name) eina_stringshare_del(sc->name); + free(sc); +} + /* Private Routines */ EOLIAN static void _edje_object_evas_object_smart_add(Eo *obj, Edje *ed) @@ -88,6 +97,7 @@ _edje_object_evas_object_smart_add(Eo *obj, Edje *ed) ed->references = 1; ed->user_defined = NULL; ed->color_classes = eina_hash_string_small_new(_edje_color_class_free); + ed->size_classes = eina_hash_string_small_new(_edje_size_class_free); evas_object_geometry_get(obj, &(ed->x), &(ed->y), &(ed->w), &(ed->h)); ed->obj = obj; diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index beb89c9..1e75041 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -18,6 +18,9 @@ static Eina_Hash *_edje_color_class_member_hash = NULL; static Eina_Hash *_edje_text_class_hash = NULL; static Eina_Hash *_edje_text_class_member_hash = NULL; +static Eina_Hash *_edje_size_class_hash = NULL; +static Eina_Hash *_edje_size_class_member_hash = NULL; + static Eina_Rbtree *_edje_box_layout_registry = NULL; char *_edje_fontset_append = NULL; @@ -47,6 +50,7 @@ struct _Edje_Refcount static Eina_Bool _edje_color_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata); static Eina_Bool _edje_text_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata); +static Eina_Bool _edje_size_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata); static void _edje_object_image_preload_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _edje_object_signal_preload_cb(void *data, Evas_Object *obj, const char *emission, const char *source); static void _edje_user_def_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child EINA_UNUSED, void *einfo EINA_UNUSED); @@ -1396,6 +1400,419 @@ _edje_object_text_class_get(Eo *obj EINA_UNUSED, Edje *ed, const char *text_clas return EINA_TRUE; } +EAPI Eina_Bool +edje_size_class_set(const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh) +{ + Eina_Hash *members; + Eina_Iterator *it; + Edje_Refcount *er; + Edje_Size_Class *sc; + + if (!size_class) return EINA_FALSE; + + sc = eina_hash_find(_edje_size_class_hash, size_class); + /* Create new size class */ + if (!sc) + { + sc = calloc(1, sizeof(Edje_Size_Class)); + if (!sc) return EINA_FALSE; + sc->name = eina_stringshare_add(size_class); + if (!sc->name) + { + free(sc); + return EINA_FALSE; + } + if (!_edje_size_class_hash) _edje_size_class_hash = eina_hash_string_superfast_new(NULL); + eina_hash_add(_edje_size_class_hash, size_class, sc); + + sc->minw = minw; + sc->minh = minh; + sc->maxw = maxw; + sc->maxh = maxh; + } + else + { + /* Match and the same, return */ + if ((sc->minw == minw) && (sc->minh == minh) && + (sc->maxw == maxw) && (sc->maxh == maxh)) + return EINA_TRUE; + + /* Update the class found */ + sc->minw = minw; + sc->minh = minh; + sc->maxw = maxw; + sc->maxh = maxh; + } + + /* Tell all members of the size class to recalc */ + members = eina_hash_find(_edje_size_class_member_hash, size_class); + 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); + } + eina_iterator_free(it); + return EINA_TRUE; +} + +EAPI Eina_Bool +edje_size_class_get(const char *size_class, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh) +{ + Edje_Size_Class *sc; + + if (!size_class) return EINA_FALSE; + + sc = eina_hash_find(_edje_size_class_hash, size_class); + + if (sc) + { + if (minw) *minw = sc->minw; + if (minh) *minh = sc->minh; + if (maxw) *maxw = sc->maxw; + if (maxh) *maxh = sc->maxh; + } + else + { + if (minw) *minw = 0; + if (minh) *minh = 0; + if (maxw) *maxw = 0; + if (maxh) *maxh = 0; + + return EINA_FALSE; + } + return EINA_TRUE; +} + +void +edje_size_class_del(const char *size_class) +{ + Edje_Size_Class *sc; + Eina_Hash *members; + Eina_Iterator *it; + Edje_Refcount *er; + + if (!size_class) return; + + sc = eina_hash_find(_edje_size_class_hash, size_class); + if (!sc) return; + + eina_hash_del(_edje_size_class_hash, size_class, sc); + eina_stringshare_del(sc->name); + free(sc); + + members = eina_hash_find(_edje_size_class_member_hash, size_class); + 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); + } + eina_iterator_free(it); +} + +Eina_List * +edje_size_class_list(void) +{ + Edje_List_Foreach_Data fdata; + + if (!_edje_size_class_hash) return NULL; + memset(&fdata, 0, sizeof(Edje_List_Foreach_Data)); + eina_hash_foreach(_edje_size_class_hash, + _edje_size_class_list_foreach, &fdata); + return fdata.list; +} + +typedef struct _Edje_Active_Size_Class_Iterator Edje_Active_Size_Class_Iterator; +struct _Edje_Active_Size_Class_Iterator +{ + Eina_Iterator iterator; + Edje_Size_Class sc; + Eina_Iterator *classes; +}; + +static Eina_Bool +_edje_size_class_active_iterator_next(Eina_Iterator *it, void **data) +{ + Edje_Active_Size_Class_Iterator *et = (void *)it; + Eina_Hash_Tuple *tuple = NULL; + Edje_Refcount *er = NULL; + Eina_Iterator *ith; + Edje_Size_Class *sc; + Eina_Bool r = EINA_FALSE; + + if (!eina_iterator_next(et->classes, (void **)&tuple)) return EINA_FALSE; + if (!tuple) return EINA_FALSE; + + ith = eina_hash_iterator_data_new(tuple->data); + if (!eina_iterator_next(ith, (void **)&er)) goto on_error; + + /* + We actually need to ask on an object to get the correct value. + It is being assumed that the size key are the same for all object here. + This can some times not be the case, but for now we should be fine. + */ + sc = _edje_size_class_find(er->ed, tuple->key); + if (!sc) goto on_error; + et->sc = *sc; + + *data = &et->sc; + r = EINA_TRUE; + + on_error: + eina_iterator_free(ith); + return r; +} + +static void * +_edje_size_class_active_iterator_container(Eina_Iterator *it EINA_UNUSED) +{ + return NULL; +} + +static void +_edje_size_class_active_iterator_free(Eina_Iterator *it) +{ + Edje_Active_Size_Class_Iterator *et = (void *)it; + + eina_iterator_free(et->classes); + EINA_MAGIC_SET(&et->iterator, 0); + free(et); +} + +EAPI Eina_Iterator * +edje_size_class_active_iterator_new(void) +{ + Edje_Active_Size_Class_Iterator *it; + + if (!_edje_size_class_member_hash) return NULL; + it = calloc(1, sizeof (Edje_Active_Size_Class_Iterator)); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + it->classes = eina_hash_iterator_tuple_new(_edje_size_class_member_hash); + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = _edje_size_class_active_iterator_next; + it->iterator.get_container = _edje_size_class_active_iterator_container; + it->iterator.free = _edje_size_class_active_iterator_free; + + return &it->iterator; +} + +static Eina_Bool +_edje_size_class_list_foreach(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata) +{ + Edje_List_Foreach_Data *fd; + + fd = fdata; + fd->list = eina_list_append(fd->list, eina_stringshare_add(key)); + return EINA_TRUE; +} + +EOLIAN Eina_Bool +_edje_object_size_class_set(Eo *obj EINA_UNUSED, Edje *ed, const char *size_class, Evas_Coord minw, Evas_Coord minh, Evas_Coord maxw, Evas_Coord maxh) +{ + Edje_Size_Class *sc = NULL; + unsigned int i; + + if ((!ed) || (!size_class)) return EINA_FALSE; + + /* for each size_class in the edje */ + sc = eina_hash_find(ed->size_classes, size_class); + + if (sc) + { + if ((sc->minw == minw) && (sc->minh == minh) && + (sc->maxw == maxw) && (sc->maxh == maxh)) + { + return EINA_TRUE; + } + + /* Update new size class properties */ + sc->minw = minw; + sc->minh = minh; + sc->maxw = maxw; + sc->maxh = maxh; + } + else + { + /* No matches, create a new size class */ + sc = calloc(1, sizeof(Edje_Size_Class)); + if (!sc) return EINA_FALSE; + sc->name = eina_stringshare_add(size_class); + if (!sc->name) + { + free(sc); + return EINA_FALSE; + } + sc->minw = minw; + sc->minh = minh; + sc->maxw = maxw; + sc->maxh = maxh; + /* Add to edje's size class list */ + eina_hash_direct_add(ed->size_classes, sc->name, sc); + } + + for (i = 0; i < ed->table_parts_size; i++) + { + Edje_Real_Part *rp; + + rp = ed->table_parts[i]; + if ((rp->part->type == EDJE_PART_TYPE_GROUP) && + ((rp->type == EDJE_RP_TYPE_SWALLOW) && + (rp->typedata.swallow)) && + (rp->typedata.swallow->swallowed_object)) + edje_object_size_class_set(rp->typedata.swallow->swallowed_object, + size_class, minw, minh, maxw, maxh); + } + + ed->dirty = EINA_TRUE; + ed->recalc_call = EINA_TRUE; +#ifdef EDJE_CALC_CACHE + ed->all_part_change = EINA_TRUE; +#endif + _edje_recalc(ed); + + return EINA_TRUE; +} + +EOLIAN Eina_Bool +_edje_object_size_class_get(Eo *obj EINA_UNUSED, Edje *ed, const char *size_class, Evas_Coord *minw, Evas_Coord *minh, Evas_Coord *maxw, Evas_Coord *maxh) +{ + Edje_Size_Class *sc = _edje_size_class_find(ed, size_class); + + if (sc) + { + if (minw) *minw = sc->minw; + if (minh) *minh = sc->minh; + if (maxw) *maxw = sc->maxw; + if (maxh) *maxh = sc->maxh; + } + else + { + if (minw) *minw = 0; + if (minh) *minh = 0; + if (maxw) *maxw = 0; + if (maxh) *maxh = 0; + + return EINA_FALSE; + } + return EINA_TRUE; +} + +EOLIAN void +_edje_object_size_class_del(Eo *obj EINA_UNUSED, Edje *ed, const char *size_class) +{ + Edje_Size_Class *sc = NULL; + unsigned int i; + + if (!size_class) return; + + eina_hash_del(ed->size_classes, size_class, sc); + + for (i = 0; i < ed->table_parts_size; i++) + { + Edje_Real_Part *rp; + + rp = ed->table_parts[i]; + if ((rp->part->type == EDJE_PART_TYPE_GROUP) && + ((rp->type == EDJE_RP_TYPE_SWALLOW) && + (rp->typedata.swallow)) && + (rp->typedata.swallow->swallowed_object)) + edje_object_size_class_del(rp->typedata.swallow->swallowed_object, size_class); + } + + ed->dirty = EINA_TRUE; + ed->recalc_call = EINA_TRUE; +#ifdef EDJE_CALC_CACHE + ed->all_part_change = EINA_TRUE; +#endif + _edje_recalc(ed); +} + +typedef struct _Edje_File_Size_Class_Iterator Edje_File_Size_Class_Iterator; +struct _Edje_File_Size_Class_Iterator +{ + Edje_Active_Size_Class_Iterator it; + Edje_File *edf; +}; + +static Eina_Bool +_edje_mmap_size_class_iterator_next(Eina_Iterator *it, void **data) +{ + Edje_File_Size_Class_Iterator *et = (void *)it; + Eina_Hash_Tuple *tuple = NULL; + Edje_Size_Class *sc = NULL; + + if (!eina_iterator_next(et->it.classes, (void **)&tuple)) return EINA_FALSE; + if (!tuple) return EINA_FALSE; + + sc = tuple->data; + + et->it.sc = *sc; + + *data = &et->it.sc; + return EINA_TRUE; +} + +static void * +_edje_mmap_size_class_iterator_container(Eina_Iterator *it) +{ + Edje_File_Size_Class_Iterator *et = (void *)it; + + return et->edf->f; +} + +static void +_edje_mmap_size_class_iterator_free(Eina_Iterator *it) +{ + Edje_File_Size_Class_Iterator *et = (void *)it; + + eina_iterator_free(et->it.classes); + _edje_cache_file_unref(et->edf); + EINA_MAGIC_SET(&et->it.iterator, 0); + free(et); +} + +EAPI Eina_Iterator * +edje_mmap_size_class_iterator_new(Eina_File *f) +{ + Edje_File_Size_Class_Iterator *it; + Edje_File *edf; + int error_ret; + + edf = _edje_cache_file_coll_open(f, NULL, &error_ret, NULL, NULL); + if (!edf) return NULL; + + it = calloc(1, sizeof (Edje_File_Size_Class_Iterator)); + if (!it) goto on_error; + + EINA_MAGIC_SET(&it->it.iterator, EINA_MAGIC_ITERATOR); + it->edf = edf; + it->it.classes = eina_hash_iterator_tuple_new(edf->size_hash); + + it->it.iterator.version = EINA_ITERATOR_VERSION; + it->it.iterator.next = _edje_mmap_size_class_iterator_next; + it->it.iterator.get_container = _edje_mmap_size_class_iterator_container; + it->it.iterator.free = _edje_mmap_size_class_iterator_free; + + return &it->it.iterator; + +on_error: + _edje_cache_file_unref(edf); + return NULL; +} + + EOLIAN Eina_Bool _edje_object_part_exists(Eo *obj EINA_UNUSED, Edje *ed, const char *part) { @@ -5414,6 +5831,74 @@ _edje_text_class_hash_free(void) _edje_text_class_hash = NULL; } +Edje_Size_Class * +_edje_size_class_find(Edje *ed, const char *size_class) +{ + Edje_Size_Class *sc; + + if ((!ed) || (!size_class)) return NULL; + + /* first look through the object scope */ + sc = eina_hash_find(ed->size_classes, size_class); + if (sc) return sc; + + /* next look through the global scope */ + sc = eina_hash_find(_edje_size_class_hash, size_class); + if (sc) return sc; + + /* finally, look through the file scope */ + sc = eina_hash_find(ed->file->size_hash, size_class); + if (sc) return sc; + + return NULL; +} + +void +_edje_size_class_member_add(Edje *ed, const char *size_class) +{ + _edje_class_member_add(ed, &_edje_size_class_member_hash, size_class); +} + +void +_edje_size_class_member_del(Edje *ed, const char *size_class) +{ + if ((!ed) || (!size_class)) return; + + _edje_class_member_del(ed, &_edje_size_class_member_hash, size_class); +} + +void +_edje_size_class_members_free(void) +{ + _edje_class_members_free(&_edje_size_class_member_hash); +} + +void +_edje_size_class_members_clean(Edje *ed) +{ + _edje_class_members_clean(ed, _edje_size_class_member_hash); +} + +static Eina_Bool +size_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED) +{ + Edje_Size_Class *sc; + + sc = data; + if (sc->name) eina_stringshare_del(sc->name); + free(sc); + return EINA_TRUE; +} + +void +_edje_size_class_hash_free(void) +{ + if (!_edje_size_class_hash) return; + eina_hash_foreach(_edje_size_class_hash, size_class_hash_list_free, NULL); + eina_hash_free(_edje_size_class_hash); + _edje_size_class_hash = NULL; +} + Edje * _edje_fetch(const Evas_Object *obj) { -- 2.7.4