#include "edje_private.h" #include "edje_container.h" #if 0 static void _edje_container_relayout(Smart_Data *sd) { Eina_List *l; Evas_Coord x, y, w, h, sw; Edje_Item *ei; if (sd->freeze > 0) return; if (!sd->need_layout) return; if (sd->w < sd->min_w) sw = sd->min_w; else if (sd->w > sd->max_w) sw = sd->max_w; else sw = sd->w; y = 0; x = 0; w = 0; h = 0; EINA_LIST_FOREACH(sd->children, l, ei) { if (sd->homogenous) h = sd->min_row_h; ei->y = y; ei->h = h; // ei->w = w; // ei->h = h; } sd->need_layout = 0; } static void _edje_container_recalc(Smart_Data *sd) { Eina_List *l; Edje_Item *ei; int any_max_h = 0, any_max_w = 0; int i; if (sd->freeze > 0) return; if (!sd->changed) return; sd->min_h = 0; sd->max_h = -1; sd->min_w = 0; sd->max_w = -1; sd->min_row_h = 0; sd->max_row_h = -1; sd->contents_h = 0; sd->contents_w = 0; for (i = 0; i < sd->cols; i++) { sd->min_w += sd->colinfo[i].minw; if (sd->colinfo[i].maxw >= 0) { if (sd->max_w >= 0) sd->max_w += sd->colinfo[i].maxw; else sd->max_w = sd->colinfo[i].maxw; } else any_max_w = 1; } if (any_max_w) sd->max_w = -1; if (sd->w < sd->min_w) sd->contents_w = sd->min_w; else if ((sd->max_w >= 0) && (sd->w < sd->max_w)) sd->w = sd->max_w; EINA_LIST_FOREACH(sd->children, l, ei) { if (ei->minh > sd->min_row_h) sd->min_row_h = ei->minh; if (sd->max_row_h >= 0) { if (ei->maxh >= 0) { if (sd->max_row_h > ei->maxh) sd->max_row_h = ei->maxh; } else any_max_h = 1; } sd->min_h += ei->minh; if (ei->maxh >= 0) { if (sd->max_h >= 0) sd->max_h += ei->maxh; else sd->max_h = ei->maxh; } else any_max_h = 1; } if (any_max_h) { sd->max_h = -1; sd->max_row_h = -1; } if (sd->homogenous) { sd->min_h = eina_list_count(sd->children) * sd->min_row_h; } sd->changed = 0; sd->change_child = 0; sd->change_child_list = 0; sd->change_cols = 0; sd->need_layout = 1; _edje_container_relayout(sd); } static void _edje_item_recalc(Edje_Item *ei) { int i; if (ei->freeze > 0) return; if (!ei->recalc) return; if (!ei->sd) return; ei->minh = 0; ei->maxh = -1; for (i = 0; i < ((Smart_Data *)(ei->sd))->cols; i++) { if (ei->cells[i].minh > ei->minh) ei->minh = ei->cells[i].minh; if (ei->cells[i].maxh >= 0) { if (ei->maxh >= 0) { if (ei->cells[i].maxh < ei->maxh) ei->maxh = ei->cells[i].maxh; } else ei->maxh = ei->cells[i].maxh; } if (((Smart_Data *)(ei->sd))->colinfo[i].minw < ei->cells[i].minw) ((Smart_Data *)(ei->sd))->colinfo[i].minw = ei->cells[i].minw; if (((Smart_Data *)(ei->sd))->colinfo[i].maxw >= 0) { if (ei->cells[i].maxw >= 0) { if (((Smart_Data *)(ei->sd))->colinfo[i].maxw > ei->cells[i].maxw) ((Smart_Data *)(ei->sd))->colinfo[i].maxw = ei->cells[i].maxw; } } else ((Smart_Data *)(ei->sd))->colinfo[i].maxw = ei->cells[i].maxw; } ei->recalc = EINA_FALSE; _edje_container_recalc(ei->sd); } /*****************************/ /** * @endcond */ /*============================================================================* * Global * *============================================================================*/ /*============================================================================* * API * *============================================================================*/ /** * @addtogroup Edje_container_Group Container * * @brief These functions provides an abstraction layer between the application * code and the interface, while allowing extremely flexible dynamic layouts * and animations. * * For more information, you can look at the @ref tutorial_list_page. * * @{ */ /** * @brief Create an edje item. * * @param cl The edje item of type Edje_Item_Class. * @param data The edje item data. * * @return The new edje item created. * * This function creates an new edje item. The edje item data can be * retrieved with edje_item_data_get(). * * @see edje_item_del() * @see edje_item_data_set() * @see edje_item_data_get() * */ Edje_Item * edje_item_add(Edje_Item_Class *cl, void *data) { Edje_Item *ei; ei = calloc(sizeof(Edje_Item), 1); ei->class = cl; ei->class_data = data; return ei; } /** * @brief Delete an edje item. * * @param ei The edje item to be deleted. * * This function deletes the edje item from memory. * * @see edje_item_add() * @see edje_item_data_set() * @see edje_item_data_get() * */ void edje_item_del(Edje_Item *ei) { Smart_Data *sd; sd = ei->sd; if (ei->object) evas_object_del(ei->object); if (ei->overlay_object) evas_object_del(ei->overlay_object); free(ei); if (!sd) return; sd->changed = 1; sd->change_child_list = 1; _edje_container_recalc(sd); } /** * @brief Return the smart object of the edje item. * * @param ei The edje item which the smart object of type Evas_Object is get * from. * * This function returns the smart object in the edje item. * */ Evas_Object * edje_item_container_get(Edje_Item *ei) { if (!ei->sd) return NULL; return ((Smart_Data *)(ei->sd))->smart_obj; } /* an arbitrary data pointer to use to track other data */ /** * @brief Set the edje item data. * * @param ei The edje item of type Edje_Item_Class. * @param data The edje item data. * * This function set the data of the edje item. The edje item data can be * retrieved with edje_item_data_get(). * * @see edje_item_add() * @see edje_item_del() * @see edje_item_data_get() * */ void edje_item_data_set(Edje_Item *ei, void *data) { ei->data = data; } /** * @brief Get the data of the edje item. * * @param ei The edje item of type Edje_Item_Class. * * This function get the data of the edje item set by edje_item_data_set(). * * @see edje_item_data_set() * @see edje_item_add() * @see edje_item_del() * */ void * edje_item_data_get(Edje_Item *ei) { return ei->data; } /* this object covers the entire item */ void edje_item_overlay_object_set(Edje_Item *ei, Evas_Object *obj) { if (ei->overlay_object) { /* FIXME: if it changed - remove...*/ } ei->overlay_object = obj; if (ei->sd) evas_object_smart_member_add(((Smart_Data *)(ei->sd))->smart_obj, obj); } Evas_Object * edje_item_overlay_object_get(Edje_Item *ei) { return ei->overlay_object; } /* this object goes under entire item */ void edje_item_object_set(Edje_Item *ei, Evas_Object *obj) { if (ei->object) { /* FIXME: if it changed - remove...*/ } ei->object = obj; if (ei->sd) evas_object_smart_member_add(((Smart_Data *)(ei->sd))->smart_obj, obj); } Evas_Object * edje_item_object_get(Edje_Item *ei) { return ei->object; } /* optionally you can manage each column's object yourself OR let Edje do it */ void edje_item_object_column_set(Edje_Item *ei, int col, Evas_Object *obj) { if (ei->cells_num <= (col + 1)) { /* FIXME: unsafe realloc */ ei->cells = realloc(ei->cells, sizeof(Edje_Item_Cell) * col); ei->cells_num = col + 1; } ei->cells[col].obj = obj; } Evas_Object * edje_item_object_column_get(Edje_Item *ei, int col) { if (ei->cells_num <= (col + 1)) return NULL; return ei->cells[col].obj; } /* query the item for the items preferred co-ords */ void edje_item_geometry_get(Edje_Item *ei, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) { if (!ei->sd) { if (x) *x = 0; if (y) *y = 0; if (w) *w = 0; if (h) *h = 0; return; } if (x) *x = ((Smart_Data *)(ei->sd))->x; if (y) *y = ((Smart_Data *)(ei->sd))->y + ei->y; if (w) *w = ((Smart_Data *)(ei->sd))->w; if (h) *h = ei->h; } /* freeze and thaw items if u are about to do a bunch of changes */ int edje_item_freeze(Edje_Item *ei) { ei->freeze++; return ei->freeze; } int edje_item_thaw(Edje_Item *ei) { ei->freeze--; if (ei->freeze > 0) return ei->freeze; if (!ei->sd) return ei->freeze; if (ei->recalc) _edje_item_recalc(ei); return ei->freeze; } /* column info */ void edje_item_column_size_set(Edje_Item *ei, int col, Evas_Coord minw, Evas_Coord maxw, Evas_Coord minh, Evas_Coord maxh) { if (ei->cells_num <= (col + 1)) { /* FIXME: unsafe realloc */ ei->cells = realloc(ei->cells, sizeof(Edje_Item_Cell) * col); ei->cells_num = col + 1; } if ((ei->cells[col].minw == minw) && (ei->cells[col].minh == minh) && (ei->cells[col].maxw == maxw) && (ei->cells[col].maxh == maxh)) return; ei->cells[col].minh = minh; ei->cells[col].maxh = maxh; ei->cells[col].minw = minw; ei->cells[col].maxw = maxw; ei->recalc = EINA_TRUE; if (ei->sd) { ((Smart_Data *)(ei->sd))->changed = 1; ((Smart_Data *)(ei->sd))->change_child = 1; } _edje_item_recalc(ei); } void edje_item_column_size_get(Edje_Item *ei, int col, Evas_Coord *minw, Evas_Coord *maxw, Evas_Coord *minh, Evas_Coord *maxh) { if (ei->cells_num <= (col + 1)) { if (minw) *minw = 0; if (minh) *minh = 0; if (maxw) *maxw = -1; if (maxh) *maxh = -1; } if (minw) *minw = ei->cells[col].minw; if (minh) *minh = ei->cells[col].minh; if (maxw) *maxw = ei->cells[col].maxw; if (maxh) *maxh = ei->cells[col].maxh; } /* selection stuff */ void edje_item_select(Edje_Item *ei) { ei->selected = 1; /* FIXME: trigger item to change visually */ } void edje_item_unselect(Edje_Item *ei) { ei->selected = 0; /* FIXME: trigger item to change visually */ } /* focus stuff - only 1 can be focuesd */ void edje_item_focus(Edje_Item *ei) { // ei->focused = 1; } void edje_item_unfocus(Edje_Item *ei) { // ei->focused = 0; } /* disable/enable stuff - stops focus and selection working on these items */ void edje_item_enable(Edje_Item *ei) { // ei->disabled = 0; } void edje_item_disable(Edje_Item *ei) { // ei->disabled = 1; } /* item utils */ int edje_item_selected_get(Edje_Item *ei) { return ei->selected; } int edje_item_focused_get(Edje_Item *ei) { return ei->focused; } int edje_item_disabled_get(Edje_Item *ei) { return ei->disabled; } /***** container calls *****/ int edje_container_freeze(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return 0; sd->freeze++; return sd->freeze; } int edje_container_thaw(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return 0; sd->freeze--; if (sd->freeze <= 0) _edje_container_recalc(sd); return sd->freeze; } void edje_container_item_append(Evas_Object *obj, Edje_Item *ei) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; sd->children = eina_list_append(sd->children, ei); sd->changed = 1; sd->change_child_list = 1; sd->rows = eina_list_count(sd->children); _edje_container_recalc(sd); } void edje_container_item_prepend(Evas_Object *obj, Edje_Item *ei) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; sd->children = eina_list_prepend(sd->children, ei); sd->changed = 1; sd->change_child_list = 1; sd->rows = eina_list_count(sd->children); _edje_container_recalc(sd); } void edje_container_item_append_relative(Evas_Object *obj, Edje_Item *ei, Edje_Item *rel) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; sd->children = eina_list_append_relative(sd->children, ei, rel); sd->changed = 1; sd->change_child_list = 1; sd->rows = eina_list_count(sd->children); _edje_container_recalc(sd); } void edje_container_item_prepend_relative(Evas_Object *obj, Edje_Item *ei, Edje_Item *rel) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; sd->children = eina_list_prepend_relative(sd->children, ei, rel); sd->changed = 1; sd->change_child_list = 1; sd->rows = eina_list_count(sd->children); _edje_container_recalc(sd); } void edje_container_item_insert(Evas_Object *obj, Edje_Item *ei, int n) { Smart_Data *sd; void *rel; sd = evas_object_smart_data_get(obj); if (!sd) return; rel = eina_list_nth(sd->children, n); if (!rel) sd->children = eina_list_append(sd->children, ei); else sd->children = eina_list_append_relative(sd->children, ei, rel); sd->changed = 1; sd->change_child_list = 1; sd->rows = eina_list_count(sd->children); _edje_container_recalc(sd); } void edje_container_item_remove(Evas_Object *obj, Edje_Item *ei) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; sd->children = eina_list_remove(sd->children, ei); sd->changed = 1; sd->change_child_list = 1; sd->rows = eina_list_count(sd->children); _edje_container_recalc(sd); } void edje_container_columns_set(Evas_Object *obj, int cols) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; if (sd->cols == cols) return; sd->colinfo = realloc(sd->colinfo, cols * sizeof(Smart_Data_Colinfo)); if (cols > sd->cols) { int i; for (i = sd->cols; i < cols; i++) { sd->colinfo[i].minw = 0; sd->colinfo[i].maxw = -1; } } sd->cols = cols; sd->changed = 1; sd->change_cols = 1; _edje_container_recalc(sd); } int edje_container_columns_get(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return 0; return sd->cols; } void edje_container_min_size_get(Evas_Object *obj, Evas_Coord *minw, Evas_Coord *minh) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; if (sd->changed) { int freeze; freeze = sd->freeze; sd->freeze = 0; _edje_container_recalc(sd); sd->freeze = freeze; } if (minw) *minw = sd->min_w; if (minh) *minh = sd->min_h; } void edje_container_max_size_get(Evas_Object *obj, Evas_Coord *maxw, Evas_Coord *maxh) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; if (sd->changed) { int freeze; freeze = sd->freeze; sd->freeze = 0; _edje_container_recalc(sd); sd->freeze = freeze; } if (maxw) *maxw = sd->max_w; if (maxh) *maxh = sd->max_h; } void edje_containter_align_set(Evas_Object *obj, double halign, double valign) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; if ((sd->align_x == halign) && (sd->align_y == valign)) return; sd->align_x = halign; sd->align_y = valign; sd->need_layout = 1; _edje_container_relayout(sd); } void edje_container_align_get(Evas_Object *obj, double *halign, double *valign) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; if (halign) *halign = sd->align_x; if (valign) *valign = sd->align_y; } int edje_container_count_get(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return 0; return eina_list_count(sd->children); } Edje_Item * edje_container_item_first_get(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return NULL; if (!sd->children) return NULL; return eina_list_data_get(sd->children); } Edje_Item * edje_container_item_last_get(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return NULL; if (!sd->children) return NULL; return0 eina_list_data_get(eina_list_last(sd->children)); } Edje_Item * edje_container_item_nth_get(Evas_Object *obj, int n) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return NULL; return eina_list_nth(sd->children, n); } void edje_container_homogenous_size_set(Evas_Object *obj, int homog) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; if (((homog) && (sd->homogenous)) || ((!homog) && (!sd->homogenous))) return; sd->homogenous = homog; sd->changed = 1; sd->change_child = 1; _edje_container_recalc(sd); } int edje_container_homogenous_size_get(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return 0; return sd->homogenous; } void edje_container_scroll_set(Evas_Object *obj, double pos, double shift) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; if ((sd->scroll_y == pos) && (sd->scroll_x == shift)) return; sd->scroll_y = pos; sd->scroll_x = shift; sd->need_layout = 1; _edje_container_relayout(sd); } void edje_container_scroll_get(Evas_Object *obj, double *pos, double *shift) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; if (pos) *pos = sd->scroll_y; if (shift) *shift = sd->scroll_x; } static void _smart_init(void); static void _smart_add(Evas_Object * obj); static void _smart_del(Evas_Object * obj); static void _smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y); static void _smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h); static void _smart_show(Evas_Object * obj); static void _smart_hide(Evas_Object * obj); static void _smart_color_set(Evas_Object * obj, int r, int g, int b, int a); static void _smart_clip_set(Evas_Object * obj, Evas_Object * clip); static void _smart_clip_unset(Evas_Object * obj); static Evas_Smart *smart = NULL; Evas_Object * edje_container_object_add(Evas *evas) { _smart_init(); return evas_object_smart_add(evas, smart); } /*******************************************/ /* Internal smart object required routines */ /*******************************************/ static void _smart_init(void) { if (smart) return; { static const Evas_Smart_Class sc = { E_OBJ_NAME, _smart_add, _smart_del, _smart_move, _smart_resize, _smart_show, _smart_hide, _smart_color_set, _smart_clip_set, _smart_clip_unset, NULL, NULL, NULL }; smart = evas_smart_class_new(&sc); } } static void _smart_add(Evas_Object *obj) { Smart_Data *sd; sd = calloc(1, sizeof(Smart_Data)); if (!sd) return; // evas_object_smart_member_add(sd->obj, obj); evas_object_smart_data_set(obj, sd); sd->smart_obj = obj; } static void _smart_del(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; if (sd->colinfo) free(sd->colinfo); // evas_object_del(sd->obj); free(sd); } static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; // evas_object_move(sd->obj, x, y); } static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; // evas_object_resize(sd->obj, w, h); } static void _smart_show(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; // evas_object_show(sd->obj); } static void _smart_hide(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; // evas_object_hide(sd->obj); } static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; // evas_object_color_set(sd->obj, r, g, b, a); } static void _smart_clip_set(Evas_Object *obj, Evas_Object *clip) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; // evas_object_clip_set(sd->obj, clip); } static void _smart_clip_unset(Evas_Object *obj) { Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return; // evas_object_clip_unset(sd->obj); } #endif