clutter控件的写法

阅读更多

clutter 1.0 document:

http://docs.clutter-project.org/docs/clutter-cookbook/1.0/

 

meego-panel-myzone/penge/penge-block-container.c source:

 

static void
penge_block_container_class_init (PengeBlockContainerClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
  GParamSpec *pspec;

  g_type_class_add_private (klass, sizeof (PengeBlockContainerPrivate));

  object_class->get_property = penge_block_container_get_property;
  object_class->set_property = penge_block_container_set_property;
  object_class->dispose = penge_block_container_dispose;
  object_class->finalize = penge_block_container_finalize;

  actor_class->get_preferred_width = penge_block_container_get_preferred_width;
  actor_class->get_preferred_height = penge_block_container_get_preferred_height;
  actor_class->allocate = penge_block_container_allocate;
  actor_class->paint = penge_block_container_paint;
  actor_class->pick = penge_block_container_pick;
... ...
}

 

/* These are needed since the layout manager allocates {0, 0, 0, 0} for
 * children it can't lay out.
 */
static void
_paint_foreach_cb (ClutterActor *actor,
                   gpointer      data)
{
  ClutterActorBox actor_box;
  gfloat w, h;

  clutter_actor_get_allocation_box (actor, &actor_box);

  clutter_actor_box_get_size (&actor_box, &w, &h);

  if (w > 0 && h > 0)
  {
    clutter_actor_paint (actor);
  }
}

static void
penge_block_container_paint (ClutterActor *actor)
{
  clutter_container_foreach (CLUTTER_CONTAINER (actor),
                             (ClutterCallback)_paint_foreach_cb,
                             actor);
}
 

 

 

static void
penge_block_container_allocate (ClutterActor           *actor,
                                const ClutterActorBox  *box,
                                ClutterAllocationFlags  flags)
{
  PengeBlockContainer *pbc = PENGE_BLOCK_CONTAINER (actor);
  PengeBlockContainerPrivate *priv = GET_PRIVATE (actor);
  GList *l, *children;
  gfloat width, height;
  gint col_span;
  gint y_count, x_count;
  ClutterActor *child;
  ClutterActorBox child_box;
  gboolean fit_found = FALSE;

  width = box->x2 - box->x1;
  height = box->y2 - box->y1;

  CLUTTER_ACTOR_CLASS (penge_block_container_parent_class)->allocate (actor,
                                                                      box,
                                                                      flags);


  if (priv->prev_width != width || priv->prev_height != height)
  {
    penge_block_container_generate_counts (pbc,
                                           width,
                                           height);
  }

  children = g_list_copy (priv->children);

  if (!children)
    return;
  children = g_list_reverse (children);

  for (y_count = 0; y_count < priv->row_count; y_count++)
  {
    for (x_count = 0; x_count < priv->column_count; /* nop */)
    {
      /* Find first that can fit */
      fit_found = FALSE;

      for (l = children; l; l = l->next)
      {
        child = (ClutterActor *)l->data;
        col_span = penge_block_container_get_child_column_span (pbc,
                                                                child);

        /* Check if it fits */
        if (x_count + col_span <= priv->column_count)
        {
          child_box.x1 = x_count * priv->actual_tile_width +
                         x_count * priv->spacing +
                         priv->padding;
          child_box.x2 = child_box.x1 +
                         priv->actual_tile_width * col_span +
                         priv->spacing * (col_span - 1);
          child_box.y1 = y_count * priv->actual_tile_height +
                         y_count * priv->spacing +
                         priv->padding;
          child_box.y2 = child_box.y1 + priv->actual_tile_height;

          clutter_actor_allocate (child, &child_box, flags);
          children = g_list_remove (children, child);
          /* Increment with the col-span to take into consideration how many
           * "blocks" we are occupying
           */
          x_count += col_span;

          fit_found = TRUE;
          break;
        }
      }

      /* If we didn't find something that fits then we just leave a gap. This
       * is basically fine.
       */
      if (!fit_found)
      {
        /* We couldn't find something that fitted */
        break;
      }
    }

    if (!children)
      break;
  }

  /* Allocate all children we don't get round to with {0,0,0,0}. We skip such
   * children in the paint.
   */
  for (l = children; l; l = l->next)
  {
    ClutterActor *actor = CLUTTER_ACTOR (l->data);
    ClutterActorBox zero_box = { 0, };
    clutter_actor_allocate (actor, &zero_box, flags);
  }

  g_list_free (children);
}

你可能感兴趣的:(MeeGo)