[layout] Initial implementation of FlowLayout
FlowLayout is a layout manager that arranges its children in a reflowing line; the orientation controls the major axis for the layout: horizontal, for reflow on the Y axis, and vertical, for reflow on the X axis.
This commit is contained in:
parent
857b0239e9
commit
5737cf869f
1
.gitignore
vendored
1
.gitignore
vendored
@ -134,6 +134,7 @@ TAGS
|
||||
/tests/interactive/test-script.json
|
||||
/tests/interactive/test-clutter-cairo-flowers
|
||||
/tests/interactive/test-box
|
||||
/tests/interactive/test-flow
|
||||
/tests/conform/stamp-test-conformance
|
||||
/tests/conform/test-anchors
|
||||
/tests/conform/test-conformance
|
||||
|
@ -77,6 +77,7 @@ source_h = \
|
||||
$(srcdir)/clutter-feature.h \
|
||||
$(srcdir)/clutter-fixed.h \
|
||||
$(srcdir)/clutter-fixed-layout.h \
|
||||
$(srcdir)/clutter-flow-layout.h \
|
||||
$(srcdir)/clutter-frame-source.h \
|
||||
$(srcdir)/clutter-group.h \
|
||||
$(srcdir)/clutter-interval.h \
|
||||
@ -146,6 +147,7 @@ source_c = \
|
||||
$(srcdir)/clutter-feature.c \
|
||||
$(srcdir)/clutter-fixed.c \
|
||||
$(srcdir)/clutter-fixed-layout.c \
|
||||
$(srcdir)/clutter-flow-layout.c \
|
||||
$(srcdir)/clutter-frame-source.c \
|
||||
$(srcdir)/clutter-group.c \
|
||||
$(srcdir)/clutter-id-pool.c \
|
||||
|
855
clutter/clutter-flow-layout.c
Normal file
855
clutter/clutter-flow-layout.c
Normal file
@ -0,0 +1,855 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:clutter-flow-layout
|
||||
* @short_description: A reflowing layout manager
|
||||
*
|
||||
* #ClutterFlowLayout is a layout manager which implements the following
|
||||
* policy:
|
||||
*
|
||||
* <itemizedlist>
|
||||
* </itemizedlist>
|
||||
*
|
||||
* #ClutterFlowLayout is available since Clutter 1.2
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter-actor.h"
|
||||
#include "clutter-animatable.h"
|
||||
#include "clutter-child-meta.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-flow-layout.h"
|
||||
#include "clutter-layout-meta.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define CLUTTER_FLOW_LAYOUT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_FLOW_LAYOUT, ClutterFlowLayoutPrivate))
|
||||
|
||||
struct _ClutterFlowLayoutPrivate
|
||||
{
|
||||
ClutterContainer *container;
|
||||
|
||||
ClutterFlowOrientation orientation;
|
||||
|
||||
gfloat col_spacing;
|
||||
gfloat row_spacing;
|
||||
|
||||
gfloat min_col_width;
|
||||
gfloat max_col_width;
|
||||
gfloat col_width;
|
||||
|
||||
gfloat min_row_height;
|
||||
gfloat max_row_height;
|
||||
gfloat row_height;
|
||||
|
||||
/* cache the preferred size; this way, if we get what we asked
|
||||
* or more then we don't have to recompute the layout
|
||||
*/
|
||||
gfloat request_width;
|
||||
gfloat request_height;
|
||||
|
||||
gint max_row_items;
|
||||
|
||||
guint layout_wrap : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_ORIENTATION,
|
||||
|
||||
PROP_COLUMN_SPACING,
|
||||
PROP_ROW_SPACING,
|
||||
|
||||
PROP_MIN_COLUMN_WIDTH,
|
||||
PROP_MAX_COLUMN_WIDTH,
|
||||
PROP_MIN_ROW_HEGHT,
|
||||
PROP_MAX_ROW_HEIGHT,
|
||||
|
||||
PROP_WRAP
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterFlowLayout,
|
||||
clutter_flow_layout,
|
||||
CLUTTER_TYPE_LAYOUT_MANAGER);
|
||||
|
||||
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;
|
||||
GList *l, *children = clutter_container_get_children (container);
|
||||
gfloat max_child_min_width, max_child_natural_width;
|
||||
gfloat row_natural_width;
|
||||
|
||||
max_child_min_width = max_child_natural_width = 0;
|
||||
row_natural_width = 0;
|
||||
|
||||
for (l = children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child = l->data;
|
||||
gfloat child_min, child_natural;
|
||||
|
||||
clutter_actor_get_preferred_width (child, for_height,
|
||||
&child_min,
|
||||
&child_natural);
|
||||
|
||||
max_child_min_width = MAX (max_child_min_width, child_min);
|
||||
max_child_natural_width = MAX (max_child_natural_width, child_natural);
|
||||
|
||||
if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
|
||||
row_natural_width += (child_natural + priv->col_spacing);
|
||||
else
|
||||
row_natural_width = MAX (row_natural_width, max_child_natural_width);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
priv->request_width = row_natural_width;
|
||||
priv->col_width = max_child_natural_width;
|
||||
|
||||
if (priv->max_col_width > 0 && priv->col_width > priv->max_col_width)
|
||||
priv->col_width = MAX (priv->max_col_width, max_child_min_width);
|
||||
|
||||
if (priv->col_width < priv->min_col_width)
|
||||
priv->col_width = priv->min_col_width;
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = ceilf (max_child_min_width);
|
||||
|
||||
if (nat_width_p)
|
||||
*nat_width_p = ceilf (row_natural_width);
|
||||
}
|
||||
|
||||
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;
|
||||
GList *l, *children = clutter_container_get_children (container);
|
||||
gfloat max_child_min_height, max_child_natural_height;
|
||||
gfloat col_natural_height;
|
||||
|
||||
max_child_min_height = max_child_natural_height = 0;
|
||||
col_natural_height = 0;
|
||||
|
||||
for (l = children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child = l->data;
|
||||
gfloat child_min, child_natural;
|
||||
|
||||
clutter_actor_get_preferred_height (child, for_width,
|
||||
&child_min,
|
||||
&child_natural);
|
||||
|
||||
max_child_min_height = MAX (max_child_min_height, child_min);
|
||||
max_child_natural_height = MAX (max_child_natural_height, child_natural);
|
||||
|
||||
if (priv->orientation == CLUTTER_FLOW_VERTICAL)
|
||||
col_natural_height += (child_natural + priv->row_spacing);
|
||||
else
|
||||
col_natural_height = MAX (col_natural_height, max_child_natural_height);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
priv->request_height = col_natural_height;
|
||||
priv->row_height = max_child_natural_height;
|
||||
|
||||
if (priv->max_row_height > 0 && priv->row_height > priv->max_row_height)
|
||||
priv->row_height = MAX (priv->max_row_height, max_child_min_height);
|
||||
|
||||
if (priv->row_height < priv->min_row_height)
|
||||
priv->row_height = priv->min_row_height;
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = ceilf (max_child_min_height);
|
||||
|
||||
if (nat_height_p)
|
||||
*nat_height_p = ceilf (col_natural_height);
|
||||
}
|
||||
|
||||
static gint
|
||||
compute_lines (ClutterFlowLayout *self,
|
||||
const GList *children,
|
||||
gfloat avail_width,
|
||||
gfloat avail_height)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv = self->priv;
|
||||
gint items_per_line;
|
||||
|
||||
if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
|
||||
items_per_line = avail_width / (priv->col_width + priv->col_spacing);
|
||||
else
|
||||
items_per_line = avail_height / (priv->row_height + priv->row_spacing);
|
||||
|
||||
return items_per_line;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_flow_layout_allocate (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
|
||||
GList *l, *children = clutter_container_get_children (container);
|
||||
gfloat avail_width, avail_height;
|
||||
gfloat item_x, item_y;
|
||||
gint line_items_count;
|
||||
gint items_per_line;
|
||||
gint line_index;
|
||||
|
||||
if (children == NULL)
|
||||
return;
|
||||
|
||||
clutter_actor_box_get_size (allocation, &avail_width, &avail_height);
|
||||
|
||||
items_per_line = compute_lines (CLUTTER_FLOW_LAYOUT (manager),
|
||||
children,
|
||||
avail_width, avail_height);
|
||||
|
||||
item_x = item_y = 0;
|
||||
|
||||
line_items_count = 0;
|
||||
line_index = 0;
|
||||
|
||||
for (l = children; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActor *child = l->data;
|
||||
ClutterActorBox child_alloc;
|
||||
gfloat item_width, item_height;
|
||||
gfloat child_min, child_natural;
|
||||
|
||||
if (line_items_count == items_per_line)
|
||||
{
|
||||
if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
|
||||
{
|
||||
item_x = 0;
|
||||
item_y += priv->row_height + priv->row_spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
item_x += priv->col_width + priv->col_spacing;
|
||||
item_y = 0;
|
||||
}
|
||||
|
||||
line_items_count = 0;
|
||||
line_index += 1;
|
||||
}
|
||||
|
||||
clutter_actor_get_preferred_width (child, priv->row_height,
|
||||
&child_min,
|
||||
&child_natural);
|
||||
item_width = MIN (child_natural, priv->col_width);
|
||||
|
||||
clutter_actor_get_preferred_height (child, item_width,
|
||||
&child_min,
|
||||
&child_natural);
|
||||
item_height = MIN (child_natural, priv->row_height);
|
||||
|
||||
CLUTTER_NOTE (LAYOUT,
|
||||
"flow[line:%d, item:%d/%d] = { %.2f, %.2f, %.2f, %.2f }",
|
||||
line_index, line_items_count, 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 += item_width;
|
||||
else
|
||||
item_y += item_height;
|
||||
|
||||
line_items_count += 1;
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_flow_layout_set_container (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
|
||||
|
||||
priv->container = container;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_flow_layout_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterFlowLayout *self = CLUTTER_FLOW_LAYOUT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ORIENTATION:
|
||||
clutter_flow_layout_set_orientation (self, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_WRAP:
|
||||
clutter_flow_layout_set_wrap (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_COLUMN_SPACING:
|
||||
clutter_flow_layout_set_column_spacing (self, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
case PROP_ROW_SPACING:
|
||||
clutter_flow_layout_set_row_spacing (self, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
case PROP_MIN_COLUMN_WIDTH:
|
||||
clutter_flow_layout_set_column_width (self,
|
||||
g_value_get_float (value),
|
||||
self->priv->max_col_width);
|
||||
break;
|
||||
|
||||
case PROP_MAX_COLUMN_WIDTH:
|
||||
clutter_flow_layout_set_column_width (self,
|
||||
self->priv->min_col_width,
|
||||
g_value_get_float (value));
|
||||
break;
|
||||
|
||||
case PROP_MIN_ROW_HEGHT:
|
||||
clutter_flow_layout_set_row_height (self,
|
||||
g_value_get_float (value),
|
||||
self->priv->max_row_height);
|
||||
break;
|
||||
|
||||
case PROP_MAX_ROW_HEIGHT:
|
||||
clutter_flow_layout_set_row_height (self,
|
||||
self->priv->min_row_height,
|
||||
g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_flow_layout_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ORIENTATION:
|
||||
g_value_set_enum (value, priv->orientation);
|
||||
break;
|
||||
|
||||
case PROP_WRAP:
|
||||
g_value_set_boolean (value, priv->layout_wrap);
|
||||
break;
|
||||
|
||||
case PROP_COLUMN_SPACING:
|
||||
g_value_set_float (value, priv->col_spacing);
|
||||
break;
|
||||
|
||||
case PROP_ROW_SPACING:
|
||||
g_value_set_float (value, priv->row_spacing);
|
||||
break;
|
||||
|
||||
case PROP_MIN_COLUMN_WIDTH:
|
||||
g_value_set_float (value, priv->min_col_width);
|
||||
break;
|
||||
|
||||
case PROP_MAX_COLUMN_WIDTH:
|
||||
g_value_set_float (value, priv->max_col_width);
|
||||
break;
|
||||
|
||||
case PROP_MIN_ROW_HEGHT:
|
||||
g_value_set_float (value, priv->min_row_height);
|
||||
break;
|
||||
|
||||
case PROP_MAX_ROW_HEIGHT:
|
||||
g_value_set_float (value, priv->max_row_height);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_flow_layout_class_init (ClutterFlowLayoutClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
ClutterLayoutManagerClass *layout_class;
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (ClutterFlowLayoutPrivate));
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (klass);
|
||||
layout_class = CLUTTER_LAYOUT_MANAGER_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = clutter_flow_layout_set_property;
|
||||
gobject_class->get_property = clutter_flow_layout_get_property;
|
||||
|
||||
layout_class->get_preferred_width =
|
||||
clutter_flow_layout_get_preferred_width;
|
||||
layout_class->get_preferred_height =
|
||||
clutter_flow_layout_get_preferred_height;
|
||||
layout_class->allocate = clutter_flow_layout_allocate;
|
||||
layout_class->set_container = clutter_flow_layout_set_container;
|
||||
|
||||
/**
|
||||
* ClutterFlowLayout:orientation:
|
||||
*
|
||||
* The orientation of the #ClutterFlowLayout. The children
|
||||
* of the layout will be layed out following the orientation.
|
||||
* If #ClutterFlowLayout:wrap is set to %TRUE then this property
|
||||
* will control the primary direction of the layout before
|
||||
* wrapping takes place
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_enum ("orientation",
|
||||
"Orientation",
|
||||
"The orientation of the layout",
|
||||
CLUTTER_TYPE_FLOW_ORIENTATION,
|
||||
CLUTTER_FLOW_HORIZONTAL,
|
||||
CLUTTER_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT);
|
||||
g_object_class_install_property (gobject_class, PROP_ORIENTATION, pspec);
|
||||
|
||||
/**
|
||||
* ClutterFlowLayout:wrap:
|
||||
*
|
||||
* Whether the layout should wrap the children to fit them
|
||||
* in the allocation. A non-wrapping layout has a preferred
|
||||
* size of the biggest child in the direction opposite to the
|
||||
* #ClutterFlowLayout:orientation property, and the sum of
|
||||
* the preferred sizes (taking into account spacing) of the
|
||||
* children in the direction of the orientation
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_boolean ("wrap",
|
||||
"Wrap",
|
||||
"Whether the layout should wrap",
|
||||
FALSE,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_WRAP, pspec);
|
||||
|
||||
/**
|
||||
* ClutterFlowLayout:column-spacing:
|
||||
*
|
||||
* The spacing between columns, in pixels; the value of this
|
||||
* property is honoured by horizontal non-wrapping layouts and
|
||||
* by vertical wrapping layouts
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_float ("column-spacing",
|
||||
"Column Spacing",
|
||||
"The spacing between columns",
|
||||
0.0, G_MAXFLOAT,
|
||||
0.0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_COLUMN_SPACING,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* ClutterFlowLayout:row-spacing:
|
||||
*
|
||||
* The spacing between rows, in pixels; the value of this
|
||||
* property is honoured by vertical non-wrapping layouts and
|
||||
* by horizontal wrapping layouts
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_float ("row-spacing",
|
||||
"Row Spacing",
|
||||
"The spacing between rows",
|
||||
0.0, G_MAXFLOAT,
|
||||
0.0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ROW_SPACING,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* ClutterFlowLayout:min-column-width:
|
||||
*
|
||||
* Minimum width for each column in the layout, in pixels
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_float ("min-column-width",
|
||||
"Minimum Column Width",
|
||||
"Minimum width for each column",
|
||||
0.0, G_MAXFLOAT,
|
||||
0.0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MIN_COLUMN_WIDTH,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* ClutterFlowLayout:max-column-width:
|
||||
*
|
||||
* Maximum width for each column in the layout, in pixels. If
|
||||
* set to -1 the width will be the maximum child width
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_float ("max-column-width",
|
||||
"Maximum Column Width",
|
||||
"Maximum width for each column",
|
||||
-1.0, G_MAXFLOAT,
|
||||
-1.0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MAX_COLUMN_WIDTH,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* ClutterFlowLayout:min-row-height:
|
||||
*
|
||||
* Minimum height for each row in the layout, in pixels
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_float ("min-row-height",
|
||||
"Minimum Row Height",
|
||||
"Minimum height for each row",
|
||||
0.0, G_MAXFLOAT,
|
||||
0.0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MIN_ROW_HEGHT,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* ClutterFlowLayout:max-row-height:
|
||||
*
|
||||
* Maximum height for each row in the layout, in pixels. If
|
||||
* set to -1 the width will be the maximum child height
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_float ("max-row-height",
|
||||
"Maximum Row Height",
|
||||
"Maximum height for each row",
|
||||
-1.0, G_MAXFLOAT,
|
||||
-1.0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MAX_ROW_HEIGHT,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_flow_layout_init (ClutterFlowLayout *self)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv;
|
||||
|
||||
self->priv = priv = CLUTTER_FLOW_LAYOUT_GET_PRIVATE (self);
|
||||
|
||||
priv->orientation = CLUTTER_FLOW_HORIZONTAL;
|
||||
|
||||
priv->col_spacing = 0;
|
||||
priv->row_spacing = 0;
|
||||
|
||||
priv->min_col_width = priv->min_row_height = 0;
|
||||
priv->max_col_width = priv->max_row_height = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_flow_layout_new:
|
||||
* @orientation: the orientation of the flow layout
|
||||
*
|
||||
* Creates a new #ClutterFlowLayout with the given @orientation
|
||||
*
|
||||
* Return value: the newly created #ClutterFlowLayout
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
ClutterLayoutManager *
|
||||
clutter_flow_layout_new (ClutterFlowOrientation orientation)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_FLOW_LAYOUT,
|
||||
"orientation", orientation,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_flow_layout_set_orientation (ClutterFlowLayout *layout,
|
||||
ClutterFlowOrientation orientation)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout));
|
||||
|
||||
priv = layout->priv;
|
||||
|
||||
if (priv->orientation != orientation)
|
||||
{
|
||||
ClutterLayoutManager *manager;
|
||||
|
||||
priv->orientation = orientation;
|
||||
|
||||
manager = CLUTTER_LAYOUT_MANAGER (layout);
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "orientation");
|
||||
}
|
||||
}
|
||||
|
||||
ClutterFlowOrientation
|
||||
clutter_flow_layout_get_orientation (ClutterFlowLayout *layout)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout),
|
||||
CLUTTER_FLOW_HORIZONTAL);
|
||||
|
||||
return layout->priv->orientation;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_flow_layout_set_wrap (ClutterFlowLayout *layout,
|
||||
gboolean wrap)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout));
|
||||
|
||||
priv = layout->priv;
|
||||
|
||||
if (priv->layout_wrap != wrap)
|
||||
{
|
||||
ClutterLayoutManager *manager;
|
||||
|
||||
priv->layout_wrap = wrap;
|
||||
|
||||
manager = CLUTTER_LAYOUT_MANAGER (layout);
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "wrap");
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_flow_layout_get_wrap (ClutterFlowLayout *layout)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout), FALSE);
|
||||
|
||||
return layout->priv->layout_wrap;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_flow_layout_set_column_spacing (ClutterFlowLayout *layout,
|
||||
gfloat spacing)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout));
|
||||
|
||||
priv = layout->priv;
|
||||
|
||||
if (priv->col_spacing != spacing)
|
||||
{
|
||||
ClutterLayoutManager *manager;
|
||||
|
||||
priv->col_spacing = spacing;
|
||||
|
||||
manager = CLUTTER_LAYOUT_MANAGER (layout);
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "column-spacing");
|
||||
}
|
||||
}
|
||||
|
||||
gfloat
|
||||
clutter_flow_layout_get_column_spacing (ClutterFlowLayout *layout)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout), 0.0);
|
||||
|
||||
return layout->priv->col_spacing;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_flow_layout_set_row_spacing (ClutterFlowLayout *layout,
|
||||
gfloat spacing)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout));
|
||||
|
||||
priv = layout->priv;
|
||||
|
||||
if (priv->row_spacing != spacing)
|
||||
{
|
||||
ClutterLayoutManager *manager;
|
||||
|
||||
priv->row_spacing = spacing;
|
||||
|
||||
manager = CLUTTER_LAYOUT_MANAGER (layout);
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "row-spacing");
|
||||
}
|
||||
}
|
||||
|
||||
gfloat
|
||||
clutter_flow_layout_get_row_spacing (ClutterFlowLayout *layout)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout), 0.0);
|
||||
|
||||
return layout->priv->row_spacing;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_flow_layout_set_column_width (ClutterFlowLayout *layout,
|
||||
gfloat min_width,
|
||||
gfloat max_width)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv;
|
||||
gboolean notify_min = FALSE, notify_max = FALSE;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout));
|
||||
|
||||
priv = layout->priv;
|
||||
|
||||
if (priv->min_col_width != min_width)
|
||||
{
|
||||
priv->min_col_width = min_width;
|
||||
|
||||
notify_min = TRUE;
|
||||
}
|
||||
|
||||
if (priv->max_col_width != max_width)
|
||||
{
|
||||
priv->max_col_width = max_width;
|
||||
|
||||
notify_max = TRUE;
|
||||
}
|
||||
|
||||
if (notify_min || notify_max)
|
||||
{
|
||||
ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (layout);
|
||||
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
}
|
||||
|
||||
if (notify_min)
|
||||
g_object_notify (G_OBJECT (layout), "min-column-width");
|
||||
|
||||
if (notify_max)
|
||||
g_object_notify (G_OBJECT (layout), "max-column-width");
|
||||
}
|
||||
|
||||
void
|
||||
clutter_flow_layout_get_column_width (ClutterFlowLayout *layout,
|
||||
gfloat *min_width,
|
||||
gfloat *max_width)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout));
|
||||
|
||||
if (min_width)
|
||||
*min_width = layout->priv->min_col_width;
|
||||
|
||||
if (max_width)
|
||||
*max_width = layout->priv->max_col_width;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_flow_layout_set_row_height (ClutterFlowLayout *layout,
|
||||
gfloat min_height,
|
||||
gfloat max_height)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv;
|
||||
gboolean notify_min = FALSE, notify_max = FALSE;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout));
|
||||
|
||||
priv = layout->priv;
|
||||
|
||||
if (priv->min_row_height != min_height)
|
||||
{
|
||||
priv->min_row_height = min_height;
|
||||
|
||||
notify_min = TRUE;
|
||||
}
|
||||
|
||||
if (priv->max_row_height != max_height)
|
||||
{
|
||||
priv->max_row_height = max_height;
|
||||
|
||||
notify_max = TRUE;
|
||||
}
|
||||
|
||||
if (notify_min || notify_max)
|
||||
{
|
||||
ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (layout);
|
||||
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
}
|
||||
|
||||
if (notify_min)
|
||||
g_object_notify (G_OBJECT (layout), "min-row-height");
|
||||
|
||||
if (notify_max)
|
||||
g_object_notify (G_OBJECT (layout), "max-row-height");
|
||||
}
|
||||
|
||||
void
|
||||
clutter_flow_layout_get_row_height (ClutterFlowLayout *layout,
|
||||
gfloat *min_height,
|
||||
gfloat *max_height)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_FLOW_LAYOUT (layout));
|
||||
|
||||
if (min_height)
|
||||
*min_height = layout->priv->min_row_height;
|
||||
|
||||
if (max_height)
|
||||
*max_height = layout->priv->max_row_height;
|
||||
}
|
127
clutter/clutter-flow-layout.h
Normal file
127
clutter/clutter-flow-layout.h
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __CLUTTER_FLOW_LAYOUT_H__
|
||||
#define __CLUTTER_FLOW_LAYOUT_H__
|
||||
|
||||
#include <clutter/clutter-layout-manager.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_FLOW_LAYOUT (clutter_flow_layout_get_type ())
|
||||
#define CLUTTER_FLOW_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_FLOW_LAYOUT, ClutterFlowLayout))
|
||||
#define CLUTTER_IS_FLOW_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_FLOW_LAYOUT))
|
||||
#define CLUTTER_FLOW_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_FLOW_LAYOUT, ClutterFlowLayoutClass))
|
||||
#define CLUTTER_IS_FLOW_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_FLOW_LAYOUT))
|
||||
#define CLUTTER_FLOW_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_FLOW_LAYOUT, ClutterFlowLayoutClass))
|
||||
|
||||
typedef struct _ClutterFlowLayout ClutterFlowLayout;
|
||||
typedef struct _ClutterFlowLayoutPrivate ClutterFlowLayoutPrivate;
|
||||
typedef struct _ClutterFlowLayoutClass ClutterFlowLayoutClass;
|
||||
|
||||
/**
|
||||
* ClutterFlowOrientation:
|
||||
* @CLUTTER_FLOW_HORIZONTAL: Arrange the children of the flow layout
|
||||
* horizontally first
|
||||
* @CLUTTER_FLOW_VERTICAL: Arrange the children of the flow layout
|
||||
* vertically first
|
||||
*
|
||||
* The direction of the arrangement of the children inside
|
||||
* a #ClutterFlowLayout
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
typedef enum { /*< prefix=CLUTTER_FLOW >*/
|
||||
CLUTTER_FLOW_HORIZONTAL,
|
||||
CLUTTER_FLOW_VERTICAL
|
||||
} ClutterFlowOrientation;
|
||||
|
||||
/**
|
||||
* ClutterFlowLayout:
|
||||
*
|
||||
* The #ClutterFlowLayout structure contains only private data
|
||||
* and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
struct _ClutterFlowLayout
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterLayoutManager parent_instance;
|
||||
|
||||
ClutterFlowLayoutPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterFlowLayoutClass:
|
||||
*
|
||||
* The #ClutterFlowLayoutClass structure contains only private data
|
||||
* and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
struct _ClutterFlowLayoutClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterLayoutManagerClass parent_class;
|
||||
};
|
||||
|
||||
GType clutter_flow_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterLayoutManager * clutter_flow_layout_new (ClutterFlowOrientation orientation);
|
||||
|
||||
void clutter_flow_layout_set_orientation (ClutterFlowLayout *layout,
|
||||
ClutterFlowOrientation orientation);
|
||||
ClutterFlowOrientation clutter_flow_layout_get_orientation (ClutterFlowLayout *layout);
|
||||
void clutter_flow_layout_set_wrap (ClutterFlowLayout *layout,
|
||||
gboolean wrap);
|
||||
gboolean clutter_flow_layout_get_wrap (ClutterFlowLayout *layout);
|
||||
|
||||
void clutter_flow_layout_set_column_spacing (ClutterFlowLayout *layout,
|
||||
gfloat spacing);
|
||||
gfloat clutter_flow_layout_get_column_spacing (ClutterFlowLayout *layout);
|
||||
void clutter_flow_layout_set_row_spacing (ClutterFlowLayout *layout,
|
||||
gfloat spacing);
|
||||
gfloat clutter_flow_layout_get_row_spacing (ClutterFlowLayout *layout);
|
||||
|
||||
void clutter_flow_layout_set_column_width (ClutterFlowLayout *layout,
|
||||
gfloat min_width,
|
||||
gfloat max_width);
|
||||
void clutter_flow_layout_get_column_width (ClutterFlowLayout *layout,
|
||||
gfloat *min_width,
|
||||
gfloat *max_width);
|
||||
void clutter_flow_layout_set_row_height (ClutterFlowLayout *layout,
|
||||
gfloat min_height,
|
||||
gfloat max_height);
|
||||
void clutter_flow_layout_get_row_height (ClutterFlowLayout *layout,
|
||||
gfloat *min_height,
|
||||
gfloat *max_height);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_FLOW_LAYOUT_H__ */
|
@ -53,6 +53,7 @@
|
||||
#include "clutter-event.h"
|
||||
#include "clutter-feature.h"
|
||||
#include "clutter-fixed-layout.h"
|
||||
#include "clutter-flow-layout.h"
|
||||
#include "clutter-frame-source.h"
|
||||
#include "clutter-group.h"
|
||||
#include "clutter-interval.h"
|
||||
|
@ -81,6 +81,7 @@
|
||||
|
||||
<xi:include href="xml/clutter-fixed-layout.xml"/>
|
||||
<xi:include href="xml/clutter-bin-layout.xml"/>
|
||||
<xi:include href="xml/clutter-flow-layout.xml"/>
|
||||
</chapter>
|
||||
|
||||
</part>
|
||||
|
@ -1847,3 +1847,37 @@ CLUTTER_LAYOUT_META_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
clutter_layout_meta_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>clutter-flow-layout</FILE>
|
||||
<TITLE>ClutterFlowLayout</TITLE>
|
||||
ClutterFlowOrientation
|
||||
ClutterFlowLayout
|
||||
ClutterFlowLayoutClass
|
||||
clutter_flow_layout_new
|
||||
clutter_flow_layout_set_orientation
|
||||
clutter_flow_layout_get_orientation
|
||||
clutter_flow_layout_set_wrap
|
||||
clutter_flow_layout_get_wrap
|
||||
|
||||
<SUBSECTION>
|
||||
clutter_flow_layout_set_column_spacing
|
||||
clutter_flow_layout_get_column_spacing
|
||||
clutter_flow_layout_set_row_spacing
|
||||
clutter_flow_layout_get_row_spacing
|
||||
clutter_flow_layout_set_column_width
|
||||
clutter_flow_layout_get_column_width
|
||||
clutter_flow_layout_set_row_height
|
||||
clutter_flow_layout_get_row_height
|
||||
|
||||
<SUBSECTION Standard>
|
||||
CLUTTER_TYPE_FLOW_LAYOUT
|
||||
CLUTTER_FLOW_LAYOUT
|
||||
CLUTTER_FLOW_LAYOUT_CLASS
|
||||
CLUTTER_IS_FLOW_LAYOUT
|
||||
CLUTTER_IS_FLOW_LAYOUT_CLASS
|
||||
CLUTTER_FLOW_LAYOUT_GET_CLASS
|
||||
<SUBSECTION Private>
|
||||
ClutterFlowLayoutPrivate
|
||||
clutter_flow_layout_get_type
|
||||
</SECTION>
|
||||
|
@ -38,3 +38,4 @@ clutter_layout_manager_get_type
|
||||
clutter_layout_meta_get_type
|
||||
clutter_fixed_layout_get_type
|
||||
clutter_bin_layout_get_type
|
||||
clutter_flow_layout_get_type
|
||||
|
@ -44,7 +44,8 @@ UNIT_TESTS = \
|
||||
test-text-field.c \
|
||||
test-clutter-cairo-flowers.c \
|
||||
test-cogl-vertex-buffer.c \
|
||||
test-box.c
|
||||
test-box.c \
|
||||
test-flow.c
|
||||
|
||||
if X11_TESTS
|
||||
UNIT_TESTS += test-pixmap.c
|
||||
|
117
tests/interactive/test-flow.c
Normal file
117
tests/interactive/test-flow.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
#include <cairo/cairo.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#define N_RECTS 20
|
||||
|
||||
static gboolean vertical = FALSE;
|
||||
static gboolean random_size = FALSE;
|
||||
static gint n_rects = N_RECTS;
|
||||
|
||||
static GOptionEntry entries[] = {
|
||||
{
|
||||
"random-size", 'r',
|
||||
0,
|
||||
G_OPTION_ARG_NONE,
|
||||
&random_size,
|
||||
"Randomly size the rectangles", NULL
|
||||
},
|
||||
{
|
||||
"num-rects", 'n',
|
||||
0,
|
||||
G_OPTION_ARG_INT,
|
||||
&n_rects,
|
||||
"Number of rectangles", "RECTS"
|
||||
},
|
||||
{
|
||||
"vertical", 'v',
|
||||
0,
|
||||
G_OPTION_ARG_NONE,
|
||||
&vertical,
|
||||
"Set vertical orientation", NULL
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_flow_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage, *box;
|
||||
ClutterLayoutManager *layout;
|
||||
ClutterColor stage_color = { 0xe0, 0xf2, 0xfc, 0xff };
|
||||
GError *error;
|
||||
gint i;
|
||||
|
||||
error = NULL;
|
||||
clutter_init_with_args (&argc, &argv,
|
||||
NULL,
|
||||
entries,
|
||||
NULL,
|
||||
&error);
|
||||
if (error)
|
||||
{
|
||||
g_print ("Unable to run test-flow: %s", error->message);
|
||||
g_error_free (error);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Flow Layout");
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
clutter_actor_set_size (stage, 640, 480);
|
||||
|
||||
layout = clutter_flow_layout_new (vertical ? CLUTTER_FLOW_VERTICAL
|
||||
: CLUTTER_FLOW_HORIZONTAL);
|
||||
|
||||
box = clutter_box_new (layout);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
|
||||
clutter_actor_set_position (box, 0, 0);
|
||||
|
||||
if (vertical)
|
||||
clutter_actor_set_height (box, 480);
|
||||
else
|
||||
clutter_actor_set_width (box, 640);
|
||||
|
||||
clutter_actor_set_name (box, "box");
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
ClutterColor color = { 255, 255, 255, 255 };
|
||||
ClutterActor *rect;
|
||||
gchar *name;
|
||||
gfloat width, height;
|
||||
|
||||
name = g_strdup_printf ("rect%02d", i);
|
||||
|
||||
clutter_color_from_hls (&color,
|
||||
360.0 / n_rects * i,
|
||||
0.5,
|
||||
0.8);
|
||||
rect = clutter_rectangle_new_with_color (&color);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (box), rect);
|
||||
|
||||
if (random_size)
|
||||
{
|
||||
width = g_random_int_range (50, 100);
|
||||
height = g_random_int_range (50, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = height = 50;
|
||||
}
|
||||
|
||||
clutter_actor_set_size (rect, width, height);
|
||||
clutter_actor_set_name (rect, name);
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user