/* Resizes the vbox to the allocated size */ static void _etk_vbox_size_allocate(Etk_Widget *widget, Etk_Geometry geometry) { Etk_VBox *vbox; Etk_Box *box; Etk_Container *container; Etk_Widget *child; Etk_Box_Cell *cell; Etk_Size requested_size; Etk_Size allocated_size; Etk_Geometry child_geometry; int num_children_to_expand = 0; int i, j; float start_offset, end_offset; float height; if (!(vbox = ETK_VBOX(widget))) return; box = ETK_BOX(vbox); container = ETK_CONTAINER(vbox); _etk_vbox_size_request(widget, &requested_size); requested_size.w -= 2 * container->border_width; requested_size.h -= 2 * container->border_width; allocated_size.w = geometry.w - 2 * container->border_width; allocated_size.h = geometry.h - 2 * container->border_width; start_offset = container->border_width; end_offset = container->border_width; if (allocated_size.h <= requested_size.h) { float ratio; ratio = (float)allocated_size.h / requested_size.h; for (i = 0; i < 2; i++) { j = (i == ETK_BOX_START) ? 0 : box->cells_count[i] - 1; cell = (i == ETK_BOX_START) ? box->first_cell[i] : box->last_cell[i]; while (cell) { child = cell->child; if (etk_widget_is_visible(child)) { height = box->request_sizes[i][j] * ratio; child_geometry.x = geometry.x + container->border_width; child_geometry.w = allocated_size.w; child_geometry.h = height; if (cell->group == ETK_BOX_START) { child_geometry.y = geometry.y + start_offset; start_offset += height + box->spacing; } else { child_geometry.y = geometry.y + geometry.h - end_offset - child_geometry.h; end_offset += height + box->spacing; } child_geometry.y += cell->padding; child_geometry.h -= 2 * cell->padding; etk_container_child_space_fill(child, &child_geometry, !(cell->fill_policy & ETK_BOX_SHRINK_OPPOSITE), cell->fill_policy & ETK_BOX_FILL, 0.5, 0.5); etk_widget_size_allocate(child, child_geometry); } cell = (i == ETK_BOX_START) ? cell->next : cell->prev; j = (i == ETK_BOX_START) ? (j + 1) : (j - 1); } } } else { float free_space; for (i = 0; i < 2; i++) { for (cell = box->first_cell[i]; cell; cell = cell->next) { child = cell->child; if (!etk_widget_is_visible(child)) continue; if (cell->fill_policy & ETK_BOX_EXPAND) num_children_to_expand++; } } if (num_children_to_expand <= 0) free_space = 0; else free_space = (float)(allocated_size.h - requested_size.h) / num_children_to_expand; for (i = 0; i < 2; i++) { j = (i == ETK_BOX_START) ? 0 : box->cells_count[i] - 1; cell = (i == ETK_BOX_START) ? box->first_cell[i] : box->last_cell[i]; while (cell) { child = cell->child; if (etk_widget_is_visible(child)) { height = box->request_sizes[i][j]; if (cell->fill_policy & ETK_BOX_EXPAND) height += free_space; child_geometry.x = geometry.x + container->border_width; child_geometry.w = allocated_size.w; child_geometry.h = height; if (cell->group == ETK_BOX_START) { child_geometry.y = geometry.y + start_offset; start_offset += height + box->spacing; } else { child_geometry.y = geometry.y + geometry.h - end_offset - child_geometry.h; end_offset += height + box->spacing; } child_geometry.y += cell->padding; child_geometry.h -= 2 * cell->padding; etk_container_child_space_fill(child, &child_geometry, !(cell->fill_policy & ETK_BOX_SHRINK_OPPOSITE), cell->fill_policy & ETK_BOX_FILL, 0.5, 0.5); etk_widget_size_allocate(child, child_geometry); } cell = (i == ETK_BOX_START) ? cell->next : cell->prev; j = (i == ETK_BOX_START) ? (j + 1) : (j - 1); } } } }
/* Resizes the table to the size allocation */ static void _etk_table_size_allocate(Etk_Widget *widget, Etk_Geometry geometry) { Etk_Table *table; Etk_Container *container; Etk_Widget *child; Etk_Table_Cell *cell; Etk_Size requested_inner_size; Etk_Size allocated_inner_size; Etk_Geometry child_geometry; float offset, size; Eina_List *l; int i; if (!(table = ETK_TABLE(widget)) || !table->cells) return; container = ETK_CONTAINER(table); _etk_table_size_request(widget, &requested_inner_size); requested_inner_size.w -= 2 * container->border_width; requested_inner_size.h -= 2 * container->border_width; allocated_inner_size.w = geometry.w - 2 * container->border_width; allocated_inner_size.h = geometry.h - 2 * container->border_width; /* We calculate the size of the cols */ offset = 0; if (requested_inner_size.w >= allocated_inner_size.w) { float ratio; ratio = (float)allocated_inner_size.w / requested_inner_size.w; for (i = 0; i < table->num_cols; i++) { size = table->cols[i].requested_size * ratio; table->cols[i].size = size; table->cols[i].offset = offset; offset += size; } } else { int num_cols_to_expand = 0; int free_space; for (i = 0; i < table->num_cols; i++) { if (table->cols[i].expand) num_cols_to_expand++; } free_space = allocated_inner_size.w - requested_inner_size.w; for (i = 0; i < table->num_cols; i++) { if (table->cols[i].expand) size = table->cols[i].requested_size + ((float)free_space / num_cols_to_expand); else size = table->cols[i].requested_size; table->cols[i].size = size; table->cols[i].offset = offset; offset += size; } } /* We calculate the size of the rows */ offset = 0; if (requested_inner_size.h >= allocated_inner_size.h) { float ratio; ratio = (float)allocated_inner_size.h / requested_inner_size.h; for (i = 0; i < table->num_rows; i++) { size = table->rows[i].requested_size * ratio; table->rows[i].size = size; table->rows[i].offset = offset; offset += size; } } else { int num_rows_to_expand = 0; int free_space; for (i = 0; i < table->num_rows; i++) { if (table->rows[i].expand) num_rows_to_expand++; } free_space = allocated_inner_size.h - requested_inner_size.h; for (i = 0; i < table->num_rows; i++) { if (table->rows[i].expand) size = table->rows[i].requested_size + ((float)free_space / num_rows_to_expand); else size = table->rows[i].requested_size; table->rows[i].size = size; table->rows[i].offset = offset; offset += size; } } /* We allocate the size for the children */ for (l = table->cells_list; l; l = l->next) { cell = l->data; child = cell->child; child_geometry.x = geometry.x + table->cols[cell->left_attach].offset + cell->x_padding; child_geometry.y = geometry.y + table->rows[cell->top_attach].offset + cell->y_padding; child_geometry.w = table->cols[cell->right_attach].offset - table->cols[cell->left_attach].offset + table->cols[cell->right_attach].size - 2 * cell->x_padding; child_geometry.h = table->rows[cell->bottom_attach].offset - table->rows[cell->top_attach].offset + table->rows[cell->bottom_attach].size - 2 * cell->y_padding; etk_container_child_space_fill(child, &child_geometry, cell->fill_policy & ETK_TABLE_HFILL, cell->fill_policy & ETK_TABLE_VFILL, 0.5, 0.5); etk_widget_size_allocate(child, child_geometry); } }