Beispiel #1
0
static void
st_table_calculate_dimensions (StTable *table,
                               gfloat for_width,
                               gfloat for_height)
{
  st_table_calculate_col_widths (table, for_width);
  st_table_calculate_row_heights (table, for_height);
}
static void
st_table_preferred_allocate (ClutterActor          *self,
                             const ClutterActorBox *content_box,
                             gboolean               flags)
{
  gint row_spacing, col_spacing;
  gint i;
  gint *col_widths, *row_heights;
  StTable *table;
  StTablePrivate *priv;
  gboolean ltr;
  ClutterActor *child;

  table = ST_TABLE (self);
  priv = ST_TABLE (self)->priv;

  col_spacing = (priv->col_spacing);
  row_spacing = (priv->row_spacing);

  col_widths =
    st_table_calculate_col_widths (table,
                                   (int) (content_box->x2 - content_box->x1));

  row_heights =
    st_table_calculate_row_heights (table,
                                    (int) (content_box->y2 - content_box->y1),
                                    col_widths);

  ltr = (clutter_actor_get_text_direction (self) == CLUTTER_TEXT_DIRECTION_LTR);

  for (child = clutter_actor_get_first_child (self);
       child != NULL;
       child = clutter_actor_get_next_sibling (child))
    {
      gint row, col, row_span, col_span;
      gint col_width, row_height;
      StTableChild *meta;
      ClutterActorBox childbox;
      gint child_x, child_y;
      gdouble x_align_f, y_align_f;

      meta = (StTableChild *) clutter_container_get_child_meta (CLUTTER_CONTAINER (self), child);

      if (!meta->allocate_hidden && !CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      /* get child properties */
      col = meta->col;
      row = meta->row;
      row_span = meta->row_span;
      col_span = meta->col_span;

      _st_get_align_factors (meta->x_align, meta->y_align,
                             &x_align_f, &y_align_f);

      /* initialise the width and height */
      col_width = col_widths[col];
      row_height = row_heights[row];

      /* Add the widths of the spanned columns:
       *
       * First check that we have a non-zero span. Then we loop over each of
       * the columns that we're spanning but we stop short if we go past the
       * number of columns in the table. This is necessary to avoid accessing
       * uninitialised memory. We add the spacing in here too since we only
       * want to add as much spacing as times we successfully span.
       */
      if (col + col_span > priv->n_cols)
        g_warning ("StTable: col-span exceeds number of columns");
#if 0
      if (row + row_span > priv->n_rows)
        g_warning ("StTable: row-span exceeds number of rows");
#endif
      if (col_span > 1)
        {
          for (i = col + 1; i < col + col_span && i < priv->n_cols; i++)
            {
              col_width += col_widths[i];
              col_width += col_spacing;
            }
        }

      /* add the height of the spanned rows */
      if (row_span > 1)
        {
          for (i = row + 1; i < row + row_span && i < priv->n_rows; i++)
            {
              row_height += row_heights[i];
              row_height += row_spacing;
            }
        }

      /* calculate child x */
      if (ltr)
        {
          child_x = (int) content_box->x1
                    + col_spacing * col;
          for (i = 0; i < col; i++)
            child_x += col_widths[i];
        }
      else
        {
          child_x = (int) content_box->x2
                    - col_spacing * col;
          for (i = 0; i < col; i++)
            child_x -= col_widths[i];
        }

      /* calculate child y */
      child_y = (int) content_box->y1
                + row_spacing * row;
      for (i = 0; i < row; i++)
        child_y += row_heights[i];

      /* set up childbox */
      if (ltr)
        {
          childbox.x1 = (float) child_x;
          childbox.x2 = (float) MAX (0, child_x + col_width);
        }
      else
        {
          childbox.x2 = (float) child_x;
          childbox.x1 = (float) MAX (0, child_x - col_width);
        }

      childbox.y1 = (float) child_y;
      childbox.y2 = (float) MAX (0, child_y + row_height);


      clutter_actor_allocate_align_fill (child, &childbox,
                                         x_align_f, y_align_f,
                                         meta->x_fill, meta->y_fill,
                                         flags);
    }
}