Пример #1
0
/* 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);
         }
      }
   }
}
Пример #2
0
/* 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);
   }
}