コード例 #1
0
/* Dump actors */
static void _xfdashboard_dump_actor_internal(ClutterActor *inActor, gint inLevel)
{
	ClutterActorIter	iter;
	ClutterActor		*child;
	gint				i;

	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
	g_return_if_fail(inLevel>=0);

	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inActor));
	while(clutter_actor_iter_next(&iter, &child))
	{
		for(i=0; i<inLevel; i++) g_print("  ");
		g_print("+- %s@%p - name: %s - geometry: %.2f,%.2f [%.2fx%.2f], mapped: %s, visible: %s, children: %d\n",
					G_OBJECT_TYPE_NAME(child), child,
					clutter_actor_get_name(child),
					clutter_actor_get_x(child),
					clutter_actor_get_y(child),
					clutter_actor_get_width(child),
					clutter_actor_get_height(child),
					clutter_actor_is_mapped(child) ? "yes" : "no",
					clutter_actor_is_visible(child) ? "yes" : "no",
					clutter_actor_get_n_children(child));
		if(clutter_actor_get_n_children(child)>0) _xfdashboard_dump_actor_internal(child, inLevel+1);
	}
}
コード例 #2
0
ファイル: utils.c プロジェクト: Pablohn26/xfdashboard
/* Dump actors */
static void _xfdashboard_dump_actor_print(ClutterActor *inActor, gint inLevel)
{
	XfdashboardStylable		*stylable;
	ClutterActorBox			allocation;
	gint					i;

	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
	g_return_if_fail(inLevel>=0);

	/* Check if actor is stylable to retrieve style configuration */
	stylable=NULL;
	if(XFDASHBOARD_IS_STYLABLE(inActor)) stylable=XFDASHBOARD_STYLABLE(inActor);

	/* Dump actor */
	for(i=0; i<inLevel; i++) g_print("  ");
	clutter_actor_get_allocation_box(inActor, &allocation);
	g_print("+- %s@%p [%s%s%s%s%s%s] - geometry: %.2f,%.2f [%.2fx%.2f], mapped: %s, visible: %s, layout: %s, children: %d\n",
				G_OBJECT_TYPE_NAME(inActor), inActor,
				clutter_actor_get_name(inActor) ? " #" : "",
				clutter_actor_get_name(inActor) ? clutter_actor_get_name(inActor) : "",
				stylable && xfdashboard_stylable_get_classes(stylable) ? "." : "",
				stylable && xfdashboard_stylable_get_classes(stylable) ? xfdashboard_stylable_get_classes(stylable) : "",
				stylable && xfdashboard_stylable_get_pseudo_classes(stylable) ? ":" : "",
				stylable && xfdashboard_stylable_get_pseudo_classes(stylable) ? xfdashboard_stylable_get_pseudo_classes(stylable) : "",
				allocation.x1,
				allocation.y1,
				allocation.x2-allocation.x1,
				allocation.y2-allocation.y1,
				clutter_actor_is_mapped(inActor) ? "yes" : "no",
				clutter_actor_is_visible(inActor) ? "yes" : "no",
				clutter_actor_get_layout_manager(inActor) ? G_OBJECT_TYPE_NAME(clutter_actor_get_layout_manager(inActor)) : "none",
				clutter_actor_get_n_children(inActor));

}
コード例 #3
0
ファイル: clutter-group.c プロジェクト: collinss/muffin
/**
 * clutter_group_get_n_children:
 * @self: A #ClutterGroup
 *
 * Gets the number of actors held in the group.
 *
 * Return value: The number of child actors held in the group.
 *
 * Since: 0.2
 *
 * Deprecated: 1.10: Use clutter_actor_get_n_children() instead.
 */
gint
clutter_group_get_n_children (ClutterGroup *self)
{
  g_return_val_if_fail (CLUTTER_IS_GROUP (self), 0);

  return clutter_actor_get_n_children (CLUTTER_ACTOR (self));
}
コード例 #4
0
static void
st_box_layout_paint (ClutterActor *actor)
{
  StBoxLayout *self = ST_BOX_LAYOUT (actor);
  StBoxLayoutPrivate *priv = self->priv;
  StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
  gdouble x, y;
  ClutterActorBox allocation_box;
  ClutterActorBox content_box;
  ClutterActor *child;

  get_border_paint_offsets (self, &x, &y);
  if (x != 0 || y != 0)
    {
      cogl_push_matrix ();
      cogl_translate ((int)x, (int)y, 0);
    }

  st_widget_paint_background (ST_WIDGET (actor));

  if (x != 0 || y != 0)
    {
      cogl_pop_matrix ();
    }

  if (clutter_actor_get_n_children (actor) == 0)
    return;

  clutter_actor_get_allocation_box (actor, &allocation_box);
  st_theme_node_get_content_box (theme_node, &allocation_box, &content_box);

  content_box.x1 += x;
  content_box.y1 += y;
  content_box.x2 += x;
  content_box.y2 += y;

  /* The content area forms the viewport into the scrolled contents, while
   * the borders and background stay in place; after drawing the borders and
   * background, we clip to the content area */
  if (priv->hadjustment || priv->vadjustment)
    cogl_clip_push_rectangle ((int)content_box.x1,
                              (int)content_box.y1,
                              (int)content_box.x2,
                              (int)content_box.y2);

  for (child = clutter_actor_get_first_child (actor);
       child != NULL;
       child = clutter_actor_get_next_sibling (child))
    clutter_actor_paint (child);

  if (priv->hadjustment || priv->vadjustment)
    cogl_clip_pop ();
}
コード例 #5
0
ファイル: clutter-group.c プロジェクト: collinss/muffin
/**
 * clutter_group_get_nth_child:
 * @self: A #ClutterGroup
 * @index_: the position of the requested actor.
 *
 * Gets a groups child held at @index_ in stack.
 *
 * Return value: (transfer none): A Clutter actor, or %NULL if
 *   @index_ is invalid.
 *
 * Since: 0.2
 *
 * Deprecated: 1.10: Use clutter_actor_get_child_at_index() instead.
 */
ClutterActor *
clutter_group_get_nth_child (ClutterGroup *self,
			     gint          index_)
{
  ClutterActor *actor;

  g_return_val_if_fail (CLUTTER_IS_GROUP (self), NULL);

  actor = CLUTTER_ACTOR (self);
  g_return_val_if_fail (index_ <= clutter_actor_get_n_children (actor), NULL);

  return clutter_actor_get_child_at_index (actor, index_);
}
コード例 #6
0
static void
st_box_layout_pick (ClutterActor       *actor,
                    const ClutterColor *color)
{
  StBoxLayout *self = ST_BOX_LAYOUT (actor);
  StBoxLayoutPrivate *priv = self->priv;
  StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
  gdouble x, y;
  ClutterActorBox allocation_box;
  ClutterActorBox content_box;
  ClutterActor *child;

  get_border_paint_offsets (self, &x, &y);
  if (x != 0 || y != 0)
    {
      cogl_push_matrix ();
      cogl_translate ((int)x, (int)y, 0);
    }

  CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->pick (actor, color);

  if (x != 0 || y != 0)
    {
      cogl_pop_matrix ();
    }

  if (clutter_actor_get_n_children (actor) == 0)
    return;

  clutter_actor_get_allocation_box (actor, &allocation_box);
  st_theme_node_get_content_box (theme_node, &allocation_box, &content_box);

  content_box.x1 += x;
  content_box.y1 += y;
  content_box.x2 += x;
  content_box.y2 += y;

  if (priv->hadjustment || priv->vadjustment)
    cogl_clip_push_rectangle ((int)content_box.x1,
                              (int)content_box.y1,
                              (int)content_box.x2,
                              (int)content_box.y2);

  for (child = clutter_actor_get_first_child (actor);
       child != NULL;
       child = clutter_actor_get_next_sibling (child))
    clutter_actor_paint (child);

  if (priv->hadjustment || priv->vadjustment)
    cogl_clip_pop ();
}
コード例 #7
0
ファイル: utils.c プロジェクト: Pablohn26/xfdashboard
static void _xfdashboard_dump_actor_internal(ClutterActor *inActor, gint inLevel)
{
	ClutterActorIter		iter;
	ClutterActor			*child;

	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
	g_return_if_fail(inLevel>0);

	/* Dump children */
	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inActor));
	while(clutter_actor_iter_next(&iter, &child))
	{
		_xfdashboard_dump_actor_print(child, inLevel);
		if(clutter_actor_get_n_children(child)>0) _xfdashboard_dump_actor_internal(child, inLevel+1);
	}
}
コード例 #8
0
ファイル: clutter-flow-layout.c プロジェクト: ebassi/clutter
static void
clutter_flow_layout_allocate (ClutterLayoutManager   *manager,
                              ClutterContainer       *container,
                              const ClutterActorBox  *allocation,
                              ClutterAllocationFlags  flags)
{
  ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
  ClutterActor *actor, *child;
  ClutterActorIter iter;
  gfloat x_off, y_off;
  gfloat avail_width, avail_height;
  gfloat item_x, item_y;
  gint line_item_count;
  gint items_per_line;
  gint line_index;

  actor = CLUTTER_ACTOR (container);
  if (clutter_actor_get_n_children (actor) == 0)
    return;

  clutter_actor_box_get_origin (allocation, &x_off, &y_off);
  clutter_actor_box_get_size (allocation, &avail_width, &avail_height);

  /* blow the cached preferred size and re-compute with the given
   * available size in case the FlowLayout wasn't given the exact
   * size it requested
   */
  if ((priv->req_width >= 0 && avail_width != priv->req_width) ||
      (priv->req_height >= 0 && avail_height != priv->req_height))
    {
      clutter_flow_layout_get_preferred_width (manager, container,
                                               avail_height,
                                               NULL, NULL);
      clutter_flow_layout_get_preferred_height (manager, container,
                                                avail_width,
                                                NULL, NULL);
    }

  items_per_line = compute_lines (CLUTTER_FLOW_LAYOUT (manager),
                                  avail_width, avail_height);

  item_x = x_off;
  item_y = y_off;

  line_item_count = 0;
  line_index = 0;

  clutter_actor_iter_init (&iter, actor);
  while (clutter_actor_iter_next (&iter, &child))
    {
      ClutterActorBox child_alloc;
      gfloat item_width, item_height;
      gfloat new_x, new_y;
      gfloat child_min, child_natural;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      new_x = new_y = 0;

      if (!priv->snap_to_grid)
        clutter_actor_get_preferred_size (child,
                                          NULL, NULL,
                                          &item_width,
                                          &item_height);

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
        {
          if ((priv->snap_to_grid &&
               line_item_count == items_per_line && line_item_count > 0) ||
              (!priv->snap_to_grid && item_x + item_width > avail_width))
            {
              item_y += g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

              if (line_index >= 0)
                item_y += priv->row_spacing;

              line_item_count = 0;
              line_index += 1;

              item_x = x_off;
            }

          if (priv->snap_to_grid)
            {
              new_x = x_off + ((line_item_count + 1) * (avail_width + priv->col_spacing))
                    / items_per_line;
              item_width = new_x - item_x - priv->col_spacing;
            }
          else
            {
              new_x = item_x + item_width + priv->col_spacing;
            }

          item_height = g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

        }
      else
        {
          if ((priv->snap_to_grid &&
               line_item_count == items_per_line && line_item_count > 0) ||
              (!priv->snap_to_grid && item_y + item_height > avail_height))
            {
              item_x += g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

              if (line_index >= 0)
                item_x += priv->col_spacing;

              line_item_count = 0;
              line_index += 1;

              item_y = y_off;
            }

          if (priv->snap_to_grid)
            {
              new_y = y_off + ((line_item_count + 1) * (avail_height + priv->row_spacing))
                    / items_per_line;
              item_height = new_y - item_y - priv->row_spacing;
            }
          else
            {
              new_y = item_y + item_height + priv->row_spacing;
            }

          item_width = g_array_index (priv->line_natural,
                                      gfloat,
                                      line_index);
        }

      if (!priv->is_homogeneous &&
          !clutter_actor_needs_expand (child,
                                       CLUTTER_ORIENTATION_HORIZONTAL))
        {
          clutter_actor_get_preferred_width (child, item_height,
                                             &child_min,
                                             &child_natural);
          item_width = MIN (item_width, child_natural);
        }

      if (!priv->is_homogeneous &&
          !clutter_actor_needs_expand (child,
                                       CLUTTER_ORIENTATION_VERTICAL))
        {
          clutter_actor_get_preferred_height (child, item_width,
                                              &child_min,
                                              &child_natural);
          item_height = MIN (item_height, child_natural);
        }

      CLUTTER_NOTE (LAYOUT,
                    "flow[line:%d, item:%d/%d] ="
                    "{ %.2f, %.2f, %.2f, %.2f }",
                    line_index, line_item_count + 1, items_per_line,
                    item_x, item_y, item_width, item_height);

      child_alloc.x1 = ceil (item_x);
      child_alloc.y1 = ceil (item_y);
      child_alloc.x2 = ceil (child_alloc.x1 + item_width);
      child_alloc.y2 = ceil (child_alloc.y1 + item_height);
      clutter_actor_allocate (child, &child_alloc, flags);

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
        item_x = new_x;
      else
        item_y = new_y;

      line_item_count += 1;
    }
}
コード例 #9
0
ファイル: clutter-flow-layout.c プロジェクト: ebassi/clutter
static void
clutter_flow_layout_get_preferred_height (ClutterLayoutManager *manager,
                                          ClutterContainer     *container,
                                          gfloat                for_width,
                                          gfloat               *min_height_p,
                                          gfloat               *nat_height_p)
{
  ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
  gint n_columns, line_item_count, line_count;
  gfloat total_min_height, total_natural_height;
  gfloat line_min_height, line_natural_height;
  gfloat max_min_height, max_natural_height;
  ClutterActor *actor, *child;
  ClutterActorIter iter;
  gfloat item_x;

  n_columns = get_columns (CLUTTER_FLOW_LAYOUT (manager), for_width);

  total_min_height = 0;
  total_natural_height = 0;

  line_min_height = 0;
  line_natural_height = 0;

  line_item_count = 0;
  line_count = 0;

  item_x = 0;

  actor = CLUTTER_ACTOR (container);

  /* clear the line height arrays */
  if (priv->line_min != NULL)
    g_array_free (priv->line_min, TRUE);

  if (priv->line_natural != NULL)
    g_array_free (priv->line_natural, TRUE);

  priv->line_min = g_array_sized_new (FALSE, FALSE,
                                      sizeof (gfloat),
                                      16);
  priv->line_natural = g_array_sized_new (FALSE, FALSE,
                                          sizeof (gfloat),
                                          16);

  if (clutter_actor_get_n_children (actor) != 0)
    line_count = 1;

  max_min_height = max_natural_height = 0;

  clutter_actor_iter_init (&iter, actor);
  while (clutter_actor_iter_next (&iter, &child))
    {
      gfloat child_min, child_natural;
      gfloat new_x, item_width;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL && for_width > 0)
        {
          clutter_actor_get_preferred_width (child, -1,
                                             &child_min,
                                             &child_natural);

          if ((priv->snap_to_grid && line_item_count == n_columns) ||
              (!priv->snap_to_grid && item_x + child_natural > for_width))
            {
              total_min_height += line_min_height;
              total_natural_height += line_natural_height;

              g_array_append_val (priv->line_min,
                                  line_min_height);
              g_array_append_val (priv->line_natural,
                                  line_natural_height);

              line_min_height = line_natural_height = 0;

              line_item_count = 0;
              line_count += 1;
              item_x = 0;
            }

          if (priv->snap_to_grid)
            {
              new_x = ((line_item_count + 1) * (for_width + priv->col_spacing))
                    / n_columns;
              item_width = new_x - item_x - priv->col_spacing;
            }
          else
            {
              new_x = item_x + child_natural + priv->col_spacing;
              item_width = child_natural;
            }

          clutter_actor_get_preferred_height (child, item_width,
                                              &child_min,
                                              &child_natural);

          line_min_height = MAX (line_min_height, child_min);
          line_natural_height = MAX (line_natural_height, child_natural);

          item_x = new_x;
          line_item_count += 1;

          max_min_height = MAX (max_min_height, line_min_height);
          max_natural_height = MAX (max_natural_height, line_natural_height);
        }
      else
        {
          clutter_actor_get_preferred_height (child, for_width,
                                              &child_min,
                                              &child_natural);

          max_min_height = MAX (max_min_height, child_min);
          max_natural_height = MAX (max_natural_height, child_natural);

          total_min_height += max_min_height;
          total_natural_height += max_natural_height;

          line_count += 1;
        }
    }

  priv->row_height = max_natural_height;

  if (priv->max_row_height > 0 && priv->row_height > priv->max_row_height)
    priv->row_height = MAX (priv->max_row_height, max_min_height);

  if (priv->row_height < priv->min_row_height)
    priv->row_height = priv->min_row_height;

  if (priv->orientation == CLUTTER_FLOW_HORIZONTAL && for_width > 0)
    {
      /* if we have a non-full row we need to add it */
      if (line_item_count > 0)
        {
          total_min_height += line_min_height;
          total_natural_height += line_natural_height;

          g_array_append_val (priv->line_min,
                              line_min_height);
          g_array_append_val (priv->line_natural,
                              line_natural_height);
        }

      priv->line_count = line_count;
      if (priv->line_count > 0)
        {
          gfloat total_spacing;

          total_spacing = priv->row_spacing * (priv->line_count - 1);

          total_min_height += total_spacing;
          total_natural_height += total_spacing;
        }
    }
  else
    {
      g_array_append_val (priv->line_min, line_min_height);
      g_array_append_val (priv->line_natural, line_natural_height);

      priv->line_count = line_count;

      if (priv->line_count > 0)
        {
          gfloat total_spacing;

          total_spacing = priv->col_spacing * priv->line_count;

          total_min_height += total_spacing;
          total_natural_height += total_spacing;
        }
    }

  CLUTTER_NOTE (LAYOUT,
                "Flow[h]: %d lines (%d per line): w [ %.2f, %.2f ] for h %.2f",
                n_columns, priv->line_count,
                total_min_height,
                total_natural_height,
                for_width);

  priv->req_width = for_width;

  if (min_height_p)
    *min_height_p = max_min_height;

  if (nat_height_p)
    *nat_height_p = total_natural_height;
}
コード例 #10
0
static void
clutter_flow_layout_get_preferred_width (ClutterLayoutManager *manager,
                                         ClutterContainer     *container,
                                         gfloat                for_height,
                                         gfloat               *min_width_p,
                                         gfloat               *nat_width_p)
{
  ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
  gint n_rows, line_item_count, line_count;
  gfloat total_min_width, total_natural_width;
  gfloat line_min_width, line_natural_width;
  gfloat max_min_width, max_natural_width;
  ClutterActor *actor, *child;
  ClutterActorIter iter;
  gfloat item_y;

  n_rows = get_rows (CLUTTER_FLOW_LAYOUT (manager), for_height);

  total_min_width = 0;
  total_natural_width = 0;

  line_min_width = 0;
  line_natural_width = 0;

  line_item_count = 0;
  line_count = 0;

  item_y = 0;

  actor = CLUTTER_ACTOR (container);

  /* clear the line width arrays */
  if (priv->line_min != NULL)
    g_array_free (priv->line_min, TRUE);

  if (priv->line_natural != NULL)
    g_array_free (priv->line_natural, TRUE);

  priv->line_min = g_array_sized_new (FALSE, FALSE,
                                      sizeof (gfloat),
                                      16);
  priv->line_natural = g_array_sized_new (FALSE, FALSE,
                                          sizeof (gfloat),
                                          16);

  if (clutter_actor_get_n_children (actor) != 0)
    line_count = 1;

  max_min_width = max_natural_width = 0;

  clutter_actor_iter_init (&iter, actor);
  while (clutter_actor_iter_next (&iter, &child))
    {
      gfloat child_min, child_natural;
      gfloat new_y, item_height;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      if (priv->orientation == CLUTTER_FLOW_VERTICAL && for_height > 0)
        {
          if (line_item_count == n_rows)
            {
              total_min_width += line_min_width;
              total_natural_width += line_natural_width;

              g_array_append_val (priv->line_min,
                                  line_min_width);
              g_array_append_val (priv->line_natural,
                                  line_natural_width);

              line_min_width = line_natural_width = 0;

              line_item_count = 0;
              line_count += 1;
              item_y = 0;
            }

          new_y = ((line_item_count + 1) * (for_height + priv->row_spacing))
                / n_rows;
          item_height = new_y - item_y - priv->row_spacing;

          clutter_actor_get_preferred_width (child, item_height,
                                             &child_min,
                                             &child_natural);

          line_min_width = MAX (line_min_width, child_min);
          line_natural_width = MAX (line_natural_width, child_natural);

          item_y = new_y;
          line_item_count += 1;

          max_min_width = MAX (max_min_width, line_min_width);
          max_natural_width = MAX (max_natural_width, line_natural_width);
        }
      else
        {
          clutter_actor_get_preferred_width (child, for_height,
                                             &child_min,
                                             &child_natural);

          max_min_width = MAX (max_min_width, child_min);
          max_natural_width = MAX (max_natural_width, child_natural);

          total_min_width += max_min_width;
          total_natural_width += max_natural_width;
          line_count += 1;
        }
    }

  priv->col_width = max_natural_width;

  if (priv->max_col_width > 0 && priv->col_width > priv->max_col_width)
    priv->col_width = MAX (priv->max_col_width, max_min_width);

  if (priv->col_width < priv->min_col_width)
    priv->col_width = priv->min_col_width;

  if (priv->orientation == CLUTTER_FLOW_VERTICAL && for_height > 0)
    {
      /* if we have a non-full row we need to add it */
      if (line_item_count > 0)
        {
          total_min_width += line_min_width;
          total_natural_width += line_natural_width;

          g_array_append_val (priv->line_min,
                              line_min_width);
          g_array_append_val (priv->line_natural,
                              line_natural_width);
        }

      priv->line_count = line_count;

      if (priv->line_count > 0)
        {
          gfloat total_spacing;

          total_spacing = priv->col_spacing * (priv->line_count - 1);

          total_min_width += total_spacing;
          total_natural_width += total_spacing;
        }
    }
  else
    {
      g_array_append_val (priv->line_min, line_min_width);
      g_array_append_val (priv->line_natural, line_natural_width);

      priv->line_count = line_count;

      if (priv->line_count > 0)
        {
          gfloat total_spacing;

          total_spacing = priv->col_spacing * (priv->line_count - 1);

          total_min_width += total_spacing;
          total_natural_width += total_spacing;
        }
    }

  CLUTTER_NOTE (LAYOUT,
                "Flow[w]: %d lines (%d per line): w [ %.2f, %.2f ] for h %.2f",
                n_rows, priv->line_count,
                total_min_width,
                total_natural_width,
                for_height);

  priv->req_height = for_height;

  if (min_width_p)
    *min_width_p = max_min_width;

  if (nat_width_p)
    *nat_width_p = total_natural_width;
}
コード例 #11
0
ファイル: st-box-layout.c プロジェクト: mtwebster/Cinnamon
static void
st_box_layout_allocate (ClutterActor          *actor,
                        const ClutterActorBox *box,
                        ClutterAllocationFlags flags)
{
  StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (actor)->priv;
  StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
  ClutterActorBox content_box;
  gfloat avail_width, avail_height, min_width, natural_width, min_height, natural_height;
  gfloat position, next_position;
  gint n_expand_children = 0, i;
  gfloat expand_amount, shrink_amount;
  BoxChildShrink *shrinks = NULL;
                 // Home-made logical xor
  gboolean flip = (!(st_widget_get_direction (ST_WIDGET (actor)) == ST_TEXT_DIRECTION_RTL) != !priv->is_align_end);
  gboolean reverse_order = (!priv->is_align_end != !priv->is_pack_start);
  ClutterActor *child;

  clutter_actor_set_allocation (actor, box, flags);

  st_theme_node_get_content_box (theme_node, box, &content_box);

  avail_width  = content_box.x2 - content_box.x1;
  avail_height = content_box.y2 - content_box.y1;

  get_content_preferred_width (ST_BOX_LAYOUT (actor), avail_height,
                               &min_width, &natural_width);
  get_content_preferred_height (ST_BOX_LAYOUT (actor), MAX (avail_width, min_width),
                                &min_height, &natural_height);


  /* update adjustments for scrolling */
  if (priv->vadjustment)
    {
      gdouble prev_value;

      g_object_set (G_OBJECT (priv->vadjustment),
                    "lower", 0.0,
                    "upper", MAX (min_height, avail_height),
                    "page-size", avail_height,
                    "step-increment", avail_height / 6,
                    "page-increment", avail_height - avail_height / 6,
                    NULL);

      prev_value = st_adjustment_get_value (priv->vadjustment);
      st_adjustment_set_value (priv->vadjustment, prev_value);
    }

  if (priv->hadjustment)
    {
      gdouble prev_value;

      g_object_set (G_OBJECT (priv->hadjustment),
                    "lower", 0.0,
                    "upper", MAX (min_width, avail_width),
                    "page-size", avail_width,
                    "step-increment", avail_width / 6,
                    "page-increment", avail_width - avail_width / 6,
                    NULL);

      prev_value = st_adjustment_get_value (priv->hadjustment);
      st_adjustment_set_value (priv->hadjustment, prev_value);
    }

  if (avail_height < min_height)
    {
      avail_height = min_height;
      content_box.y2 = content_box.y1 + avail_height;
    }

  if (avail_width < min_width)
    {
      avail_width = min_width;
      content_box.x2 = content_box.x1 + avail_width;
    }

  if (priv->is_vertical)
    {
      expand_amount = MAX (0, avail_height - natural_height);
      shrink_amount = MAX (0, natural_height - avail_height);
    }
  else
    {
      expand_amount = MAX (0, avail_width - natural_width);
      shrink_amount = MAX (0, natural_width - avail_width);
    }


  if (expand_amount > 0)
    {
      /* count the number of children with expand set to TRUE */
      n_expand_children = 0;
      for (child = clutter_actor_get_first_child (actor);
           child != NULL;
           child = clutter_actor_get_next_sibling (child))
        {
          gboolean expand;

          if (!CLUTTER_ACTOR_IS_VISIBLE (child) ||
              clutter_actor_get_fixed_position_set (child))
            continue;

          clutter_container_child_get ((ClutterContainer *) actor,
                                       child,
                                       "expand", &expand,
                                       NULL);
          if (expand)
            n_expand_children++;
        }

      if (n_expand_children == 0)
        expand_amount = 0;
    }
  else if (shrink_amount > 0)
    {
      shrinks = compute_shrinks (ST_BOX_LAYOUT (actor),
                                 priv->is_vertical ? avail_width : avail_height,
                                 shrink_amount);
     }

  if (priv->is_vertical)
    {
      if (flip)
        {
          position = content_box.y2;
        }
      else
        {
          position = content_box.y1;
        }
    }
  else
    {
      if (flip)
        {
          position = content_box.x2;
        }
      else
        {
          position = content_box.x1;
        }
    }

  if (reverse_order)
    {
      child = clutter_actor_get_last_child (actor);
      i = clutter_actor_get_n_children (actor) - 1;
    }
  else
    {
      child = clutter_actor_get_first_child (actor);
      i = 0;
    }
    
  gfloat init_padding = (avail_width/2) - (natural_width/2);
  while (child != NULL)
    {
      ClutterActorBox child_box;
      gfloat child_min, child_nat, child_allocated;
      gboolean xfill, yfill, expand, fixed;
      StAlign xalign, yalign;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        goto next_child;

      fixed = clutter_actor_get_fixed_position_set (child);
      if (fixed)
        {
          clutter_actor_allocate_preferred_size (child, flags);
          goto next_child;
        }

      clutter_container_child_get ((ClutterContainer*) actor, child,
                                   "x-fill", &xfill,
                                   "y-fill", &yfill,
                                   "x-align", &xalign,
                                   "y-align", &yalign,
                                   "expand", &expand,
                                   NULL);

      if (priv->is_vertical)
        {
          _st_actor_get_preferred_height (child, avail_width, xfill,
                                          &child_min, &child_nat);
        }
      else
        {
          _st_actor_get_preferred_width (child, avail_height, yfill,
                                         &child_min, &child_nat);
        }

      child_allocated = child_nat;
      if (expand_amount > 0 && expand)
        child_allocated +=  expand_amount / n_expand_children;
      else if (shrink_amount > 0)
        child_allocated -= shrinks[i].shrink_amount;

      if (flip) {
        next_position = position - child_allocated;
      }
      else {
        next_position = position + child_allocated;
      }

      if (priv->is_vertical)
        {
          if (flip)
            {
              child_box.y1 = (int)(0.5 + next_position);
              child_box.y2 = (int)(0.5 + position);
            }
          else
            {
              child_box.y1 = (int)(0.5 + position);
              child_box.y2 = (int)(0.5 + next_position);
            }

          child_box.x1 = content_box.x1;
          child_box.x2 = content_box.x2;

          _st_allocate_fill (ST_WIDGET (actor), child, &child_box,
                             xalign, yalign, xfill, yfill);
          clutter_actor_allocate (child, &child_box, flags);
        }
      else
        {
          if (flip)
            {
              child_box.x1 = (int)(0.5 + next_position);
              child_box.x2 = (int)(0.5 + position);
            }
          else
            {
              child_box.x1 = (int)(0.5 + position);
              child_box.x2 = (int)(0.5 + next_position);
            }

          child_box.y1 = content_box.y1;
          child_box.y2 = content_box.y2;

          _st_allocate_fill (ST_WIDGET (actor), child, &child_box,
                             xalign, yalign, xfill, yfill);
          clutter_actor_allocate (child, &child_box, flags);
        }

      if (flip)
        position = next_position - priv->spacing;
      else
        position = next_position + priv->spacing;

    next_child:
      if (reverse_order)
        {
          child = clutter_actor_get_previous_sibling (child);
          i--;
        }
      else
        {
          child = clutter_actor_get_next_sibling (child);
          i++;
        }
    }

  if (shrinks)
    g_free (shrinks);
}
コード例 #12
0
ファイル: st-box-layout.c プロジェクト: mtwebster/Cinnamon
static BoxChildShrink *
compute_shrinks (StBoxLayout *self,
                 gfloat       for_length,
                 gfloat       total_shrink)
{
  StBoxLayoutPrivate *priv = self->priv;
  int n_children = clutter_actor_get_n_children (CLUTTER_ACTOR (self));
  BoxChildShrink *shrinks = g_new0 (BoxChildShrink, n_children);
  gfloat shrink_so_far;
  gfloat base_shrink = 0; /* the "= 0" is just to make gcc happy */
  int n_shrink_children;
  ClutterActor *child;
  int i = 0;

  /* The effect that we want is that all the children get an equal chance
   * to expand from their minimum size up to the natural size. Or to put
   * it a different way, we want to start by shrinking only the child that
   * can shrink most, then shrink that and the next most shrinkable child,
   * to the point where we are shrinking everything.
   */

  /* Find the amount of possible shrink for each child */
  int n_possible_shrink_children = 0;
  for (child = clutter_actor_get_first_child (CLUTTER_ACTOR (self));
       child != NULL;
       child = clutter_actor_get_next_sibling (child))
    {
      gfloat child_min, child_nat;
      gboolean child_fill;
      gboolean fixed;

      fixed = clutter_actor_get_fixed_position_set (child);

      shrinks[i].child_index = i;
      if (CLUTTER_ACTOR_IS_VISIBLE (child) && !fixed)
        {
          if (priv->is_vertical)
            {
              clutter_container_child_get ((ClutterContainer*) self, child,
                                           "x-fill", &child_fill,
                                           NULL);
              _st_actor_get_preferred_height (child,
                                              for_length, child_fill,
                                              &child_min, &child_nat);
            }
          else
            {
              clutter_container_child_get ((ClutterContainer*) self, child,
                                           "y-fill", &child_fill,
                                           NULL);
              _st_actor_get_preferred_width (child,
                                             for_length, child_fill,
                                             &child_min, &child_nat);
            }

          shrinks[i].shrink_amount = MAX (0., child_nat - child_min);
          n_possible_shrink_children++;
        }
      else
        {
          shrinks[i].shrink_amount = -1.;
        }

      i++;
    }

  /* We want to process children starting from the child with the maximum available
   * shrink, so sort in this order; !visible children end up at the end */
  qsort (shrinks, n_children, sizeof (BoxChildShrink), compare_by_shrink_amount);

  /*   +--+
   *   |  |
   *   |  | +--
   *   |  | | |
   *   |  | | | +-+
   * --+--+-+-+-+-+----------
   *   |  | | | | | +-+ +-+
   *   |  | | | | | | | | |
   * --+--+-+-+-+-+-+-+------
   *
   * We are trying to find the correct position for the upper line the "water mark"
   * so that total of the portion of the bars above the line is equal to the total
   * amount we want to shrink.
   */

  /* Start by moving the line downward, top-of-bar by top-of-bar */
  shrink_so_far = 0;
  for (n_shrink_children = 1; n_shrink_children <= n_possible_shrink_children; n_shrink_children++)
    {
      if (n_shrink_children < n_possible_shrink_children)
        base_shrink = shrinks[n_shrink_children].shrink_amount;
      else
        base_shrink = 0;
      shrink_so_far += n_shrink_children * (shrinks[n_shrink_children - 1].shrink_amount - base_shrink);

      if (shrink_so_far >= total_shrink || n_shrink_children == n_possible_shrink_children)
        break;
    }

  /* OK, we found enough shrinkage, move it back upwards to the right position */
  base_shrink += (shrink_so_far - total_shrink) / n_shrink_children;
  if (base_shrink < 0) /* can't shrink that much, probably round-off error */
    base_shrink = 0;

  /* Assign the portion above the base shrink line to the shrink_amount */
  for (i = 0; i < n_shrink_children; i++)
    shrinks[i].shrink_amount -= base_shrink;
  for (; i < n_children; i++)
    shrinks[i].shrink_amount = 0;

  /* And sort back to their original order */
  qsort (shrinks, n_children, sizeof (BoxChildShrink), compare_by_child_index);

  return shrinks;
}
コード例 #13
0
ファイル: clutter-table-layout.c プロジェクト: UIKit0/clutter
static void
clutter_table_layout_allocate (ClutterLayoutManager   *layout,
                               ClutterContainer       *container,
                               const ClutterActorBox  *box,
                               ClutterAllocationFlags  flags)
{
  ClutterTableLayout *self = CLUTTER_TABLE_LAYOUT (layout);
  ClutterTableLayoutPrivate *priv = self->priv;
  ClutterActor *actor, *child;
  gint row_spacing, col_spacing;
  gint i;
  DimensionData *rows, *columns;

  update_row_col (self, container);
  if (priv->n_cols < 1 || priv->n_rows < 1)
    return;

  actor = CLUTTER_ACTOR (container);

  if (clutter_actor_get_n_children (actor) == 0)
    return;

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

  calculate_table_dimensions (self, container,
                              box->x2 - box->x1,
                              box->y2 - box->y1);

  rows = (DimensionData *) (void *) priv->rows->data;
  columns = (DimensionData *) (void *) priv->columns->data;

  for (child = clutter_actor_get_first_child (actor);
       child != NULL;
       child = clutter_actor_get_next_sibling (child))
    {
      gint row, col, row_span, col_span;
      gint col_width, row_height;
      ClutterTableChild *meta;
      ClutterActorBox childbox;
      gint child_x, child_y;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      meta =
        CLUTTER_TABLE_CHILD (clutter_layout_manager_get_child_meta (layout,
                                                                    container,
                                                                    child));

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

      /* initialise the width and height */
      col_width = columns[col].final_size;
      row_height = rows[row].final_size;

      /* 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 (G_STRLOC ": column-span exceeds number of columns");
      if (row + row_span > priv->n_rows)
        g_warning (G_STRLOC ": row-span exceeds number of rows");

      if (col_span > 1)
        {
          for (i = col + 1; i < col + col_span && i < priv->n_cols; i++)
            {
              col_width += columns[i].final_size;
              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 += rows[i].final_size;
              row_height += row_spacing;
            }
        }

      /* calculate child x */
      child_x = clutter_actor_box_get_x (box);
      for (i = 0; i < col; i++)
        {
          if (columns[i].visible)
            {
              child_x += columns[i].final_size;
              child_x += col_spacing;
            }
        }

      /* calculate child y */
      child_y = clutter_actor_box_get_y (box);
      for (i = 0; i < row; i++)
        {
          if (rows[i].visible)
            {
              child_y += rows[i].final_size;
              child_y += row_spacing;
            }
        }

      /* set up childbox */
      childbox.x1 = (float) child_x;
      childbox.x2 = (float) MAX (0, child_x + col_width);

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

      clutter_actor_allocate (child, &childbox, flags);
    }
}