mirror of
https://github.com/brl/mutter.git
synced 2025-02-18 06:04:10 +00:00
Merge branch 'layout-manager'
* layout-manager: (50 commits) docs: Reword a link layout, docs: Add more documentation to LayoutManager layout, docs: Fix description of Bin properties layout, bin: Use ceilf() instead of casting to int layout, docs: Add long description for FlowLayout layout, box: Clean up layout, box: Write long description for Box layout, docs: Remove unused functions layout: Document BoxLayout layout: Add BoxLayout, a single line layout manager layout: Report the correct size of FlowLayout layout: Resizing the stage resizes the FlowLayout box layout: Use the get_request_mode() getter in BinLayout layout: Change the request-mode along with the orientation actor: Add set_request_mode() method [layout] Remove FlowLayout:wrap [layout] Rename BinLayout and FlowLayout interactive tests [layout] Skip invisible children in FlowLayout [layout] Clean up and document FlowLayout [layout] Snap children of FlowLayout to column/row ...
This commit is contained in:
commit
ba25571c8e
3
.gitignore
vendored
3
.gitignore
vendored
@ -132,6 +132,9 @@ TAGS
|
|||||||
/tests/interactive/redhand_alpha.png
|
/tests/interactive/redhand_alpha.png
|
||||||
/tests/interactive/test-script.json
|
/tests/interactive/test-script.json
|
||||||
/tests/interactive/test-clutter-cairo-flowers
|
/tests/interactive/test-clutter-cairo-flowers
|
||||||
|
/tests/interactive/test-bin-layout
|
||||||
|
/tests/interactive/test-flow-layout
|
||||||
|
/tests/interactive/test-box-layout
|
||||||
/tests/conform/stamp-test-conformance
|
/tests/conform/stamp-test-conformance
|
||||||
/tests/conform/test-anchors
|
/tests/conform/test-anchors
|
||||||
/tests/conform/test-conformance
|
/tests/conform/test-conformance
|
||||||
|
@ -64,6 +64,9 @@ source_h = \
|
|||||||
$(srcdir)/clutter-behaviour-rotate.h \
|
$(srcdir)/clutter-behaviour-rotate.h \
|
||||||
$(srcdir)/clutter-behaviour-scale.h \
|
$(srcdir)/clutter-behaviour-scale.h \
|
||||||
$(srcdir)/clutter-binding-pool.h \
|
$(srcdir)/clutter-binding-pool.h \
|
||||||
|
$(srcdir)/clutter-bin-layout.h \
|
||||||
|
$(srcdir)/clutter-box.h \
|
||||||
|
$(srcdir)/clutter-box-layout.h \
|
||||||
$(srcdir)/clutter-cairo-texture.h \
|
$(srcdir)/clutter-cairo-texture.h \
|
||||||
$(srcdir)/clutter-child-meta.h \
|
$(srcdir)/clutter-child-meta.h \
|
||||||
$(srcdir)/clutter-clone.h \
|
$(srcdir)/clutter-clone.h \
|
||||||
@ -73,10 +76,14 @@ source_h = \
|
|||||||
$(srcdir)/clutter-event.h \
|
$(srcdir)/clutter-event.h \
|
||||||
$(srcdir)/clutter-feature.h \
|
$(srcdir)/clutter-feature.h \
|
||||||
$(srcdir)/clutter-fixed.h \
|
$(srcdir)/clutter-fixed.h \
|
||||||
|
$(srcdir)/clutter-fixed-layout.h \
|
||||||
|
$(srcdir)/clutter-flow-layout.h \
|
||||||
$(srcdir)/clutter-frame-source.h \
|
$(srcdir)/clutter-frame-source.h \
|
||||||
$(srcdir)/clutter-group.h \
|
$(srcdir)/clutter-group.h \
|
||||||
$(srcdir)/clutter-interval.h \
|
$(srcdir)/clutter-interval.h \
|
||||||
$(srcdir)/clutter-keysyms.h \
|
$(srcdir)/clutter-keysyms.h \
|
||||||
|
$(srcdir)/clutter-layout-manager.h \
|
||||||
|
$(srcdir)/clutter-layout-meta.h \
|
||||||
$(srcdir)/clutter-list-model.h \
|
$(srcdir)/clutter-list-model.h \
|
||||||
$(srcdir)/clutter-main.h \
|
$(srcdir)/clutter-main.h \
|
||||||
$(srcdir)/clutter-media.h \
|
$(srcdir)/clutter-media.h \
|
||||||
@ -128,6 +135,9 @@ source_c = \
|
|||||||
$(srcdir)/clutter-behaviour-scale.c \
|
$(srcdir)/clutter-behaviour-scale.c \
|
||||||
$(srcdir)/clutter-bezier.c \
|
$(srcdir)/clutter-bezier.c \
|
||||||
$(srcdir)/clutter-binding-pool.c \
|
$(srcdir)/clutter-binding-pool.c \
|
||||||
|
$(srcdir)/clutter-bin-layout.c \
|
||||||
|
$(srcdir)/clutter-box.c \
|
||||||
|
$(srcdir)/clutter-box-layout.c \
|
||||||
$(srcdir)/clutter-cairo-texture.c \
|
$(srcdir)/clutter-cairo-texture.c \
|
||||||
$(srcdir)/clutter-child-meta.c \
|
$(srcdir)/clutter-child-meta.c \
|
||||||
$(srcdir)/clutter-clone.c \
|
$(srcdir)/clutter-clone.c \
|
||||||
@ -137,10 +147,14 @@ source_c = \
|
|||||||
$(srcdir)/clutter-event.c \
|
$(srcdir)/clutter-event.c \
|
||||||
$(srcdir)/clutter-feature.c \
|
$(srcdir)/clutter-feature.c \
|
||||||
$(srcdir)/clutter-fixed.c \
|
$(srcdir)/clutter-fixed.c \
|
||||||
|
$(srcdir)/clutter-fixed-layout.c \
|
||||||
|
$(srcdir)/clutter-flow-layout.c \
|
||||||
$(srcdir)/clutter-frame-source.c \
|
$(srcdir)/clutter-frame-source.c \
|
||||||
$(srcdir)/clutter-group.c \
|
$(srcdir)/clutter-group.c \
|
||||||
$(srcdir)/clutter-id-pool.c \
|
$(srcdir)/clutter-id-pool.c \
|
||||||
$(srcdir)/clutter-interval.c \
|
$(srcdir)/clutter-interval.c \
|
||||||
|
$(srcdir)/clutter-layout-manager.c \
|
||||||
|
$(srcdir)/clutter-layout-meta.c \
|
||||||
$(srcdir)/clutter-list-model.c \
|
$(srcdir)/clutter-list-model.c \
|
||||||
$(srcdir)/clutter-main.c \
|
$(srcdir)/clutter-main.c \
|
||||||
clutter-marshal.c \
|
clutter-marshal.c \
|
||||||
|
@ -473,8 +473,6 @@ static void clutter_actor_set_natural_width_set (ClutterActor *self,
|
|||||||
gboolean use_natural_width);
|
gboolean use_natural_width);
|
||||||
static void clutter_actor_set_natural_height_set (ClutterActor *self,
|
static void clutter_actor_set_natural_height_set (ClutterActor *self,
|
||||||
gboolean use_natural_height);
|
gboolean use_natural_height);
|
||||||
static void clutter_actor_set_request_mode (ClutterActor *self,
|
|
||||||
ClutterRequestMode mode);
|
|
||||||
static void clutter_actor_update_map_state (ClutterActor *self,
|
static void clutter_actor_update_map_state (ClutterActor *self,
|
||||||
MapStateChange change);
|
MapStateChange change);
|
||||||
static void clutter_actor_unrealize_not_hiding (ClutterActor *self);
|
static void clutter_actor_unrealize_not_hiding (ClutterActor *self);
|
||||||
@ -3297,7 +3295,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
|||||||
* gfloat natural_width, min_width;
|
* gfloat natural_width, min_width;
|
||||||
* gfloat natural_height, min_height;
|
* gfloat natural_height, min_height;
|
||||||
*
|
*
|
||||||
* g_object_get (G_OBJECT (child), "request-mode", &mode, NULL);
|
* mode = clutter_actor_get_request_mode (child);
|
||||||
* if (mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
|
* if (mode == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
|
||||||
* {
|
* {
|
||||||
* clutter_actor_get_preferred_width (child, -1,
|
* clutter_actor_get_preferred_width (child, -1,
|
||||||
@ -5184,11 +5182,28 @@ clutter_actor_set_natural_height_set (ClutterActor *self,
|
|||||||
clutter_actor_queue_relayout (self);
|
clutter_actor_queue_relayout (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/**
|
||||||
|
* clutter_actor_set_request_mode:
|
||||||
|
* @self: a #ClutterActor
|
||||||
|
* @mode: the request mode
|
||||||
|
*
|
||||||
|
* Sets the geometry request mode of @self.
|
||||||
|
*
|
||||||
|
* The @mode determines the order for invoking
|
||||||
|
* clutter_actor_get_preferred_width() and
|
||||||
|
* clutter_actor_get_preferred_height()
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
clutter_actor_set_request_mode (ClutterActor *self,
|
clutter_actor_set_request_mode (ClutterActor *self,
|
||||||
ClutterRequestMode mode)
|
ClutterRequestMode mode)
|
||||||
{
|
{
|
||||||
ClutterActorPrivate *priv = self->priv;
|
ClutterActorPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
if (priv->request_mode == mode)
|
if (priv->request_mode == mode)
|
||||||
return;
|
return;
|
||||||
@ -5203,6 +5218,25 @@ clutter_actor_set_request_mode (ClutterActor *self,
|
|||||||
clutter_actor_queue_relayout (self);
|
clutter_actor_queue_relayout (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_actor_get_request_mode:
|
||||||
|
* @self: a #ClutterActor
|
||||||
|
*
|
||||||
|
* Retrieves the geometry request mode of @self
|
||||||
|
*
|
||||||
|
* Return value: the request mode for the actor
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
ClutterRequestMode
|
||||||
|
clutter_actor_get_request_mode (ClutterActor *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_ACTOR (self),
|
||||||
|
CLUTTER_REQUEST_HEIGHT_FOR_WIDTH);
|
||||||
|
|
||||||
|
return self->priv->request_mode;
|
||||||
|
}
|
||||||
|
|
||||||
/* variant of set_width() without checks and without notification
|
/* variant of set_width() without checks and without notification
|
||||||
* freeze+thaw, for internal usage only
|
* freeze+thaw, for internal usage only
|
||||||
*/
|
*/
|
||||||
|
@ -301,6 +301,9 @@ void clutter_actor_queue_relayout (ClutterActor
|
|||||||
void clutter_actor_destroy (ClutterActor *self);
|
void clutter_actor_destroy (ClutterActor *self);
|
||||||
|
|
||||||
/* size negotiation */
|
/* size negotiation */
|
||||||
|
void clutter_actor_set_request_mode (ClutterActor *self,
|
||||||
|
ClutterRequestMode mode);
|
||||||
|
ClutterRequestMode clutter_actor_get_request_mode (ClutterActor *self);
|
||||||
void clutter_actor_get_preferred_width (ClutterActor *self,
|
void clutter_actor_get_preferred_width (ClutterActor *self,
|
||||||
gfloat for_height,
|
gfloat for_height,
|
||||||
gfloat *min_width_p,
|
gfloat *min_width_p,
|
||||||
|
865
clutter/clutter-bin-layout.c
Normal file
865
clutter/clutter-bin-layout.c
Normal file
@ -0,0 +1,865 @@
|
|||||||
|
/*
|
||||||
|
* 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-bin-layout
|
||||||
|
* @short_description: A simple layout manager
|
||||||
|
*
|
||||||
|
* #ClutterBinLayout is a layout manager which implements the following
|
||||||
|
* policy:
|
||||||
|
*
|
||||||
|
* <itemizedlist>
|
||||||
|
* <listitem><simpara>the preferred size is the maximum preferred size
|
||||||
|
* between all the children of the container using the
|
||||||
|
* layout;</simpara></listitem>
|
||||||
|
* <listitem><simpara>each child is allocated in "layers", on on top
|
||||||
|
* of the other;</simpara></listitem>
|
||||||
|
* <listitem><simpara>for each layer there are horizontal and vertical
|
||||||
|
* alignment policies.</simpara></listitem>
|
||||||
|
* </itemizedlist>
|
||||||
|
*
|
||||||
|
* <example id="example-clutter-bin-layout">
|
||||||
|
* <title>How to pack actors inside a BinLayout</title>
|
||||||
|
* <para>The following code shows how to build a composite actor with
|
||||||
|
* a texture and a background, and add controls overlayed on top. The
|
||||||
|
* background is set to fill the whole allocation, whilst the texture
|
||||||
|
* is centered; there is a control in the top right corner and a label
|
||||||
|
* in the bottom, filling out the whole allocated width.</para>
|
||||||
|
* <programlisting>
|
||||||
|
* ClutterLayoutManager *manager;
|
||||||
|
* ClutterActor *box;
|
||||||
|
*
|
||||||
|
* /* create the layout first */
|
||||||
|
* layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
|
* CLUTTER_BIN_ALIGNMENT_CENTER);
|
||||||
|
* box = clutter_box_new (layout); /* then the container */
|
||||||
|
*
|
||||||
|
* /* we can use the layout object to add actors */
|
||||||
|
* clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (layout), background,
|
||||||
|
* CLUTTER_BIN_ALIGNMENT_FILL,
|
||||||
|
* CLUTTER_BIN_ALIGNMENT_FILL);
|
||||||
|
* clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (layout), icon,
|
||||||
|
* CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
|
* CLUTTER_BIN_ALIGNMENT_CENTER);
|
||||||
|
*
|
||||||
|
* /* align to the bottom left */
|
||||||
|
* clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (layout), label,
|
||||||
|
* CLUTTER_BIN_ALIGNMENT_START,
|
||||||
|
* CLUTTER_BIN_ALIGNMENT_END);
|
||||||
|
* /* align to the top right */
|
||||||
|
* clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (layout), button,
|
||||||
|
* CLUTTER_BIN_ALIGNMENT_END,
|
||||||
|
* CLUTTER_BIN_ALIGNMENT_START);
|
||||||
|
* </programlisting>
|
||||||
|
* </example>
|
||||||
|
*
|
||||||
|
* #ClutterBinLayout 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-bin-layout.h"
|
||||||
|
#include "clutter-child-meta.h"
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-enum-types.h"
|
||||||
|
#include "clutter-layout-meta.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_BIN_LAYER (clutter_bin_layer_get_type ())
|
||||||
|
#define CLUTTER_BIN_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIN_LAYER, ClutterBinLayer))
|
||||||
|
#define CLUTTER_IS_BIN_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIN_LAYER))
|
||||||
|
|
||||||
|
#define CLUTTER_BIN_LAYOUT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayoutPrivate))
|
||||||
|
|
||||||
|
typedef struct _ClutterBinLayer ClutterBinLayer;
|
||||||
|
typedef struct _ClutterLayoutMetaClass ClutterBinLayerClass;
|
||||||
|
|
||||||
|
struct _ClutterBinLayoutPrivate
|
||||||
|
{
|
||||||
|
ClutterBinAlignment x_align;
|
||||||
|
ClutterBinAlignment y_align;
|
||||||
|
|
||||||
|
ClutterContainer *container;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ClutterBinLayer
|
||||||
|
{
|
||||||
|
ClutterLayoutMeta parent_instance;
|
||||||
|
|
||||||
|
ClutterBinAlignment x_align;
|
||||||
|
ClutterBinAlignment y_align;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_LAYER_0,
|
||||||
|
|
||||||
|
PROP_LAYER_X_ALIGN,
|
||||||
|
PROP_LAYER_Y_ALIGN
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_X_ALIGN,
|
||||||
|
PROP_Y_ALIGN
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ClutterBinLayer,
|
||||||
|
clutter_bin_layer,
|
||||||
|
CLUTTER_TYPE_LAYOUT_META);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ClutterBinLayout,
|
||||||
|
clutter_bin_layout,
|
||||||
|
CLUTTER_TYPE_LAYOUT_MANAGER);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ClutterBinLayer
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_layer_x_align (ClutterBinLayer *self,
|
||||||
|
ClutterBinAlignment alignment)
|
||||||
|
{
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
|
||||||
|
if (self->x_align == alignment)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->x_align = alignment;
|
||||||
|
|
||||||
|
meta = CLUTTER_LAYOUT_META (self);
|
||||||
|
manager = clutter_layout_meta_get_manager (meta);
|
||||||
|
clutter_layout_manager_layout_changed (manager);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (self), "x-align");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_layer_y_align (ClutterBinLayer *self,
|
||||||
|
ClutterBinAlignment alignment)
|
||||||
|
{
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
|
||||||
|
if (self->y_align == alignment)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->y_align = alignment;
|
||||||
|
|
||||||
|
meta = CLUTTER_LAYOUT_META (self);
|
||||||
|
manager = clutter_layout_meta_get_manager (meta);
|
||||||
|
clutter_layout_manager_layout_changed (manager);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (self), "y-align");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layer_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterBinLayer *layer = CLUTTER_BIN_LAYER (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LAYER_X_ALIGN:
|
||||||
|
set_layer_x_align (layer, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_LAYER_Y_ALIGN:
|
||||||
|
set_layer_y_align (layer, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layer_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterBinLayer *layer = CLUTTER_BIN_LAYER (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LAYER_X_ALIGN:
|
||||||
|
g_value_set_enum (value, layer->x_align);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_LAYER_Y_ALIGN:
|
||||||
|
g_value_set_enum (value, layer->y_align);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layer_class_init (ClutterBinLayerClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
gobject_class->set_property = clutter_bin_layer_set_property;
|
||||||
|
gobject_class->get_property = clutter_bin_layer_get_property;
|
||||||
|
|
||||||
|
pspec = g_param_spec_enum ("x-align",
|
||||||
|
"Horizontal Alignment",
|
||||||
|
"Horizontal alignment for the actor "
|
||||||
|
"inside the layer",
|
||||||
|
CLUTTER_TYPE_BIN_ALIGNMENT,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_LAYER_X_ALIGN,
|
||||||
|
pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_enum ("y-align",
|
||||||
|
"Vertical Alignment",
|
||||||
|
"Vertical alignment for the actor "
|
||||||
|
"inside the layer manager",
|
||||||
|
CLUTTER_TYPE_BIN_ALIGNMENT,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_LAYER_Y_ALIGN,
|
||||||
|
pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layer_init (ClutterBinLayer *layer)
|
||||||
|
{
|
||||||
|
layer->x_align = CLUTTER_BIN_ALIGNMENT_CENTER;
|
||||||
|
layer->y_align = CLUTTER_BIN_ALIGNMENT_CENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ClutterBinLayout
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_x_align (ClutterBinLayout *self,
|
||||||
|
ClutterBinAlignment alignment)
|
||||||
|
{
|
||||||
|
ClutterBinLayoutPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->x_align != alignment)
|
||||||
|
{
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
|
||||||
|
priv->x_align = alignment;
|
||||||
|
|
||||||
|
manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||||
|
clutter_layout_manager_layout_changed (manager);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (self), "x-align");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_y_align (ClutterBinLayout *self,
|
||||||
|
ClutterBinAlignment alignment)
|
||||||
|
{
|
||||||
|
ClutterBinLayoutPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->y_align != alignment)
|
||||||
|
{
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
|
||||||
|
priv->y_align = alignment;
|
||||||
|
|
||||||
|
manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||||
|
clutter_layout_manager_layout_changed (manager);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (self), "y-align");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layout_get_preferred_width (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_height,
|
||||||
|
gfloat *min_width_p,
|
||||||
|
gfloat *nat_width_p)
|
||||||
|
{
|
||||||
|
GList *children = clutter_container_get_children (container);
|
||||||
|
GList *l;
|
||||||
|
gfloat min_width, nat_width;
|
||||||
|
|
||||||
|
min_width = nat_width = 0.0;
|
||||||
|
|
||||||
|
for (l = children; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
ClutterActor *child = l->data;
|
||||||
|
gfloat minimum, natural;
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_width (child, for_height,
|
||||||
|
&minimum,
|
||||||
|
&natural);
|
||||||
|
|
||||||
|
min_width = MAX (min_width, minimum);
|
||||||
|
nat_width = MAX (nat_width, natural);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min_width_p)
|
||||||
|
*min_width_p = min_width;
|
||||||
|
|
||||||
|
if (nat_width_p)
|
||||||
|
*nat_width_p = nat_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layout_get_preferred_height (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_width,
|
||||||
|
gfloat *min_height_p,
|
||||||
|
gfloat *nat_height_p)
|
||||||
|
{
|
||||||
|
GList *children = clutter_container_get_children (container);
|
||||||
|
GList *l;
|
||||||
|
gfloat min_height, nat_height;
|
||||||
|
|
||||||
|
min_height = nat_height = 0.0;
|
||||||
|
|
||||||
|
for (l = children; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
ClutterActor *child = l->data;
|
||||||
|
gfloat minimum, natural;
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_height (child, for_width,
|
||||||
|
&minimum,
|
||||||
|
&natural);
|
||||||
|
|
||||||
|
min_height = MAX (min_height, minimum);
|
||||||
|
nat_height = MAX (nat_height, natural);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min_height_p)
|
||||||
|
*min_height_p = min_height;
|
||||||
|
|
||||||
|
if (nat_height_p)
|
||||||
|
*nat_height_p = nat_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gdouble
|
||||||
|
get_bin_alignment_factor (ClutterBinAlignment alignment)
|
||||||
|
{
|
||||||
|
switch (alignment)
|
||||||
|
{
|
||||||
|
case CLUTTER_BIN_ALIGNMENT_CENTER:
|
||||||
|
return 0.5;
|
||||||
|
|
||||||
|
case CLUTTER_BIN_ALIGNMENT_START:
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
case CLUTTER_BIN_ALIGNMENT_END:
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
|
case CLUTTER_BIN_ALIGNMENT_FIXED:
|
||||||
|
case CLUTTER_BIN_ALIGNMENT_FILL:
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
const ClutterActorBox *allocation,
|
||||||
|
ClutterAllocationFlags flags)
|
||||||
|
{
|
||||||
|
GList *children = clutter_container_get_children (container);
|
||||||
|
GList *l;
|
||||||
|
gfloat available_w, available_h;
|
||||||
|
|
||||||
|
available_w = clutter_actor_box_get_width (allocation);
|
||||||
|
available_h = clutter_actor_box_get_height (allocation);
|
||||||
|
|
||||||
|
for (l = children; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
ClutterActor *child = l->data;
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
ClutterBinLayer *layer;
|
||||||
|
ClutterActorBox child_alloc = { 0, };
|
||||||
|
gfloat child_width, child_height;
|
||||||
|
ClutterRequestMode request;
|
||||||
|
|
||||||
|
meta = clutter_layout_manager_get_child_meta (manager,
|
||||||
|
container,
|
||||||
|
child);
|
||||||
|
layer = CLUTTER_BIN_LAYER (meta);
|
||||||
|
|
||||||
|
if (layer->x_align == CLUTTER_BIN_ALIGNMENT_FILL)
|
||||||
|
{
|
||||||
|
child_alloc.x1 = 0;
|
||||||
|
child_alloc.x2 = ceilf (available_w);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer->y_align == CLUTTER_BIN_ALIGNMENT_FILL)
|
||||||
|
{
|
||||||
|
child_alloc.y1 = 0;
|
||||||
|
child_alloc.y2 = ceilf (available_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we are filling horizontally and vertically then we
|
||||||
|
* can break here because we already have a full allocation
|
||||||
|
*/
|
||||||
|
if (layer->x_align == CLUTTER_BIN_ALIGNMENT_FILL &&
|
||||||
|
layer->y_align == CLUTTER_BIN_ALIGNMENT_FILL)
|
||||||
|
{
|
||||||
|
clutter_actor_allocate (child, &child_alloc, flags);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = clutter_actor_get_request_mode (child);
|
||||||
|
if (request == CLUTTER_REQUEST_HEIGHT_FOR_WIDTH)
|
||||||
|
{
|
||||||
|
gfloat min_width, nat_width;
|
||||||
|
gfloat min_height, nat_height;
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_width (child, available_h,
|
||||||
|
&min_width,
|
||||||
|
&nat_width);
|
||||||
|
child_width = CLAMP (nat_width, min_width, available_w);
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_height (child, child_width,
|
||||||
|
&min_height,
|
||||||
|
&nat_height);
|
||||||
|
child_height = CLAMP (nat_height, min_height, available_h);
|
||||||
|
}
|
||||||
|
else if (request == CLUTTER_REQUEST_WIDTH_FOR_HEIGHT)
|
||||||
|
{
|
||||||
|
gfloat min_width, nat_width;
|
||||||
|
gfloat min_height, nat_height;
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_height (child, available_w,
|
||||||
|
&min_height,
|
||||||
|
&nat_height);
|
||||||
|
child_height = CLAMP (nat_height, min_height, available_h);
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_width (child, child_height,
|
||||||
|
&min_width,
|
||||||
|
&nat_width);
|
||||||
|
child_width = CLAMP (nat_width, min_width, available_w);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer->x_align == CLUTTER_BIN_ALIGNMENT_FIXED)
|
||||||
|
{
|
||||||
|
child_alloc.x1 = ceilf (clutter_actor_get_x (child));
|
||||||
|
child_alloc.x2 = ceilf (child_alloc.x1 + child_width);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gdouble x_align = get_bin_alignment_factor (layer->x_align);
|
||||||
|
|
||||||
|
if (layer->x_align != CLUTTER_BIN_ALIGNMENT_FILL)
|
||||||
|
{
|
||||||
|
child_alloc.x1 = ceilf ((available_w - child_width) * x_align);
|
||||||
|
child_alloc.x2 = ceilf (child_alloc.x1 + child_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer->y_align == CLUTTER_BIN_ALIGNMENT_FIXED)
|
||||||
|
{
|
||||||
|
child_alloc.y1 = ceilf (clutter_actor_get_y (child));
|
||||||
|
child_alloc.y2 = ceilf (child_alloc.y1 + child_height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gdouble y_align = get_bin_alignment_factor (layer->y_align);
|
||||||
|
|
||||||
|
if (layer->y_align != CLUTTER_BIN_ALIGNMENT_FILL)
|
||||||
|
{
|
||||||
|
child_alloc.y1 = ceilf ((available_h - child_height) * y_align);
|
||||||
|
child_alloc.y2 = ceilf (child_alloc.y1 + child_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_allocate (child, &child_alloc, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (children);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterLayoutMeta *
|
||||||
|
clutter_bin_layout_create_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterBinLayoutPrivate *priv;
|
||||||
|
|
||||||
|
priv = CLUTTER_BIN_LAYOUT (manager)->priv;
|
||||||
|
|
||||||
|
return g_object_new (CLUTTER_TYPE_BIN_LAYER,
|
||||||
|
"container", container,
|
||||||
|
"actor", actor,
|
||||||
|
"manager", manager,
|
||||||
|
"x-align", priv->x_align,
|
||||||
|
"y_align", priv->y_align,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layout_set_container (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container)
|
||||||
|
{
|
||||||
|
ClutterBinLayoutPrivate *priv;
|
||||||
|
|
||||||
|
priv = CLUTTER_BIN_LAYOUT (manager)->priv;
|
||||||
|
priv->container = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layout_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterBinLayout *layout = CLUTTER_BIN_LAYOUT (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_X_ALIGN:
|
||||||
|
set_x_align (layout, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_Y_ALIGN:
|
||||||
|
set_y_align (layout, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layout_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterBinLayoutPrivate *priv;
|
||||||
|
|
||||||
|
priv = CLUTTER_BIN_LAYOUT (gobject)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_X_ALIGN:
|
||||||
|
g_value_set_enum (value, priv->x_align);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_Y_ALIGN:
|
||||||
|
g_value_set_enum (value, priv->y_align);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layout_class_init (ClutterBinLayoutClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterLayoutManagerClass *layout_class =
|
||||||
|
CLUTTER_LAYOUT_MANAGER_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (ClutterBinLayoutPrivate));
|
||||||
|
|
||||||
|
gobject_class->set_property = clutter_bin_layout_set_property;
|
||||||
|
gobject_class->get_property = clutter_bin_layout_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBinLayout:x-align:
|
||||||
|
*
|
||||||
|
* The default horizontal alignment policy for actors managed
|
||||||
|
* by the #ClutterBinLayout
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_enum ("x-align",
|
||||||
|
"Horizontal Alignment",
|
||||||
|
"Default horizontal alignment for the actors "
|
||||||
|
"inside the layout manager",
|
||||||
|
CLUTTER_TYPE_BIN_ALIGNMENT,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_X_ALIGN, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBinLayout:y-align:
|
||||||
|
*
|
||||||
|
* The default vertical alignment policy for actors managed
|
||||||
|
* by the #ClutterBinLayout
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_enum ("y-align",
|
||||||
|
"Vertical Alignment",
|
||||||
|
"Default vertical alignment for the actors "
|
||||||
|
"inside the layout manager",
|
||||||
|
CLUTTER_TYPE_BIN_ALIGNMENT,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_Y_ALIGN, pspec);
|
||||||
|
|
||||||
|
layout_class->get_preferred_width =
|
||||||
|
clutter_bin_layout_get_preferred_width;
|
||||||
|
layout_class->get_preferred_height =
|
||||||
|
clutter_bin_layout_get_preferred_height;
|
||||||
|
layout_class->allocate =
|
||||||
|
clutter_bin_layout_allocate;
|
||||||
|
layout_class->create_child_meta =
|
||||||
|
clutter_bin_layout_create_child_meta;
|
||||||
|
layout_class->set_container =
|
||||||
|
clutter_bin_layout_set_container;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_bin_layout_init (ClutterBinLayout *self)
|
||||||
|
{
|
||||||
|
self->priv = CLUTTER_BIN_LAYOUT_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
self->priv->x_align = CLUTTER_BIN_ALIGNMENT_CENTER;
|
||||||
|
self->priv->y_align = CLUTTER_BIN_ALIGNMENT_CENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_bin_layout_new:
|
||||||
|
* @x_align: the default alignment policy to be used on the
|
||||||
|
* horizontal axis
|
||||||
|
* @y_align: the default alignment policy to be used on the
|
||||||
|
* vertical axis
|
||||||
|
*
|
||||||
|
* Creates a new #ClutterBinLayout layout manager
|
||||||
|
*
|
||||||
|
* Return value: the newly created layout manager
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
ClutterLayoutManager *
|
||||||
|
clutter_bin_layout_new (ClutterBinAlignment x_align,
|
||||||
|
ClutterBinAlignment y_align)
|
||||||
|
{
|
||||||
|
return g_object_new (CLUTTER_TYPE_BIN_LAYOUT,
|
||||||
|
"x-align", x_align,
|
||||||
|
"y-align", y_align,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_bin_layout_set_alignment:
|
||||||
|
* @self: a #ClutterBinLayout
|
||||||
|
* @child: (allow-none): a child of @container
|
||||||
|
* @x_align: the horizontal alignment policy to be used for the @child
|
||||||
|
* inside @container
|
||||||
|
* @y_align: the vertical aligment policy to be used on the @child
|
||||||
|
* inside @container
|
||||||
|
*
|
||||||
|
* Sets the horizontal and vertical alignment policies to be applied
|
||||||
|
* to a @child of @self
|
||||||
|
*
|
||||||
|
* If @child is %NULL then the @x_align and @y_align values will
|
||||||
|
* be set as the default alignment policies
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_bin_layout_set_alignment (ClutterBinLayout *self,
|
||||||
|
ClutterActor *child,
|
||||||
|
ClutterBinAlignment x_align,
|
||||||
|
ClutterBinAlignment y_align)
|
||||||
|
{
|
||||||
|
ClutterBinLayoutPrivate *priv;
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
|
||||||
|
g_return_if_fail (child == NULL || CLUTTER_IS_ACTOR (child));
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->container == NULL)
|
||||||
|
{
|
||||||
|
if (child == NULL)
|
||||||
|
{
|
||||||
|
set_x_align (self, x_align);
|
||||||
|
set_y_align (self, y_align);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning ("The layout of type '%s' must be associated to "
|
||||||
|
"a ClutterContainer before setting the alignment "
|
||||||
|
"on its children",
|
||||||
|
G_OBJECT_TYPE_NAME (self));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||||
|
meta = clutter_layout_manager_get_child_meta (manager,
|
||||||
|
priv->container,
|
||||||
|
child);
|
||||||
|
g_assert (CLUTTER_IS_BIN_LAYER (meta));
|
||||||
|
|
||||||
|
set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align);
|
||||||
|
set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_bin_layout_get_alignment:
|
||||||
|
* @self: a #ClutterBinLayout
|
||||||
|
* @child: (allow-none): a child of @container
|
||||||
|
* @x_align: (out) (allow-none): return location for the horizontal
|
||||||
|
* alignment policy
|
||||||
|
* @y_align: (out) (allow-none): return location for the vertical
|
||||||
|
* alignment policy
|
||||||
|
*
|
||||||
|
* Retrieves the horizontal and vertical alignment policies for
|
||||||
|
* a child of @self
|
||||||
|
*
|
||||||
|
* If @child is %NULL the default alignment policies will be returned
|
||||||
|
* instead
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_bin_layout_get_alignment (ClutterBinLayout *self,
|
||||||
|
ClutterActor *child,
|
||||||
|
ClutterBinAlignment *x_align,
|
||||||
|
ClutterBinAlignment *y_align)
|
||||||
|
{
|
||||||
|
ClutterBinLayoutPrivate *priv;
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
ClutterBinLayer *layer;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->container == NULL)
|
||||||
|
{
|
||||||
|
if (child == NULL)
|
||||||
|
{
|
||||||
|
if (x_align)
|
||||||
|
*x_align = priv->x_align;
|
||||||
|
|
||||||
|
if (y_align)
|
||||||
|
*y_align = priv->y_align;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning ("The layout of type '%s' must be associated to "
|
||||||
|
"a ClutterContainer before getting the alignment "
|
||||||
|
"of its children",
|
||||||
|
G_OBJECT_TYPE_NAME (self));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||||
|
meta = clutter_layout_manager_get_child_meta (manager,
|
||||||
|
priv->container,
|
||||||
|
child);
|
||||||
|
g_assert (CLUTTER_IS_BIN_LAYER (meta));
|
||||||
|
|
||||||
|
layer = CLUTTER_BIN_LAYER (meta);
|
||||||
|
|
||||||
|
if (x_align)
|
||||||
|
*x_align = layer->x_align;
|
||||||
|
|
||||||
|
if (y_align)
|
||||||
|
*y_align = layer->y_align;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_bin_layout_add:
|
||||||
|
* @self: a #ClutterBinLayout
|
||||||
|
* @child: a #ClutterActor
|
||||||
|
* @x_align: horizontal alignment policy for @child
|
||||||
|
* @y_align: vertical alignment policy for @child
|
||||||
|
*
|
||||||
|
* Adds a #ClutterActor to the container using @self and
|
||||||
|
* sets the alignment policies for it
|
||||||
|
*
|
||||||
|
* This function is equivalent to clutter_container_add_actor()
|
||||||
|
* and clutter_layout_manager_child_set_property() but it does not
|
||||||
|
* require a pointer to the #ClutterContainer associated to the
|
||||||
|
* #ClutterBinLayout
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_bin_layout_add (ClutterBinLayout *self,
|
||||||
|
ClutterActor *child,
|
||||||
|
ClutterBinAlignment x_align,
|
||||||
|
ClutterBinAlignment y_align)
|
||||||
|
{
|
||||||
|
ClutterBinLayoutPrivate *priv;
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (child));
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->container == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("The layout of type '%s' must be associated to "
|
||||||
|
"a ClutterContainer before adding children",
|
||||||
|
G_OBJECT_TYPE_NAME (self));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_container_add_actor (priv->container, child);
|
||||||
|
|
||||||
|
manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||||
|
meta = clutter_layout_manager_get_child_meta (manager,
|
||||||
|
priv->container,
|
||||||
|
child);
|
||||||
|
g_assert (CLUTTER_IS_BIN_LAYER (meta));
|
||||||
|
|
||||||
|
set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align);
|
||||||
|
set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align);
|
||||||
|
}
|
123
clutter/clutter-bin-layout.h
Normal file
123
clutter/clutter-bin-layout.h
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* 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_BIN_LAYOUT_H__
|
||||||
|
#define __CLUTTER_BIN_LAYOUT_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-layout-manager.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_BIN_LAYOUT (clutter_bin_layout_get_type ())
|
||||||
|
#define CLUTTER_BIN_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayout))
|
||||||
|
#define CLUTTER_IS_BIN_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIN_LAYOUT))
|
||||||
|
#define CLUTTER_BIN_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayoutClass))
|
||||||
|
#define CLUTTER_IS_BIN_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BIN_LAYOUT))
|
||||||
|
#define CLUTTER_BIN_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayoutClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterBinLayout ClutterBinLayout;
|
||||||
|
typedef struct _ClutterBinLayoutPrivate ClutterBinLayoutPrivate;
|
||||||
|
typedef struct _ClutterBinLayoutClass ClutterBinLayoutClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBinAlignment:
|
||||||
|
* @CLUTTER_BIN_ALIGNMENT_FIXED: Fixed position alignment; the
|
||||||
|
* #ClutterBinLayout will honour the fixed position provided
|
||||||
|
* by the actors themselves when allocating them
|
||||||
|
* @CLUTTER_BIN_ALIGNMENT_FILL: Fill the allocation size
|
||||||
|
* @CLUTTER_BIN_ALIGNMENT_START: Position the actors at the top
|
||||||
|
* or left side of the container, depending on the axis
|
||||||
|
* @CLUTTER_BIN_ALIGNMENT_END: Position the actors at the bottom
|
||||||
|
* or right side of the container, depending on the axis
|
||||||
|
* @CLUTTER_BIN_ALIGNMENT_CENTER: Position the actors at the
|
||||||
|
* center of the container, depending on the axis
|
||||||
|
*
|
||||||
|
* The alignment policies available on each axis for #ClutterBinLayout
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CLUTTER_BIN_ALIGNMENT_FIXED,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_FILL,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_START,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_END,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER
|
||||||
|
} ClutterBinAlignment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBinLayout:
|
||||||
|
*
|
||||||
|
* The #ClutterBinLayout structure contains only private data
|
||||||
|
* and should be accessed using the provided API
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _ClutterBinLayout
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterLayoutManager parent_instance;
|
||||||
|
|
||||||
|
ClutterBinLayoutPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBinLayoutClass:
|
||||||
|
*
|
||||||
|
* The #ClutterBinLayoutClass structure contains only private
|
||||||
|
* data and should be accessed using the provided API
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _ClutterBinLayoutClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterLayoutManagerClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_bin_layout_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterLayoutManager *clutter_bin_layout_new (ClutterBinAlignment x_align,
|
||||||
|
ClutterBinAlignment y_align);
|
||||||
|
|
||||||
|
void clutter_bin_layout_set_alignment (ClutterBinLayout *self,
|
||||||
|
ClutterActor *child,
|
||||||
|
ClutterBinAlignment x_align,
|
||||||
|
ClutterBinAlignment y_align);
|
||||||
|
void clutter_bin_layout_get_alignment (ClutterBinLayout *self,
|
||||||
|
ClutterActor *child,
|
||||||
|
ClutterBinAlignment *x_align,
|
||||||
|
ClutterBinAlignment *y_align);
|
||||||
|
|
||||||
|
void clutter_bin_layout_add (ClutterBinLayout *self,
|
||||||
|
ClutterActor *child,
|
||||||
|
ClutterBinAlignment x_align,
|
||||||
|
ClutterBinAlignment y_align);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_BIN_LAYOUT_H__ */
|
1496
clutter/clutter-box-layout.c
Normal file
1496
clutter/clutter-box-layout.c
Normal file
File diff suppressed because it is too large
Load Diff
143
clutter/clutter-box-layout.h
Normal file
143
clutter/clutter-box-layout.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
*
|
||||||
|
* Based on the NBTK NbtkBoxLayout actor by:
|
||||||
|
* Thomas Wood <thomas.wood@intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||||
|
#error "Only <clutter/clutter.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CLUTTER_BOX_LAYOUT_H__
|
||||||
|
#define __CLUTTER_BOX_LAYOUT_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-layout-manager.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_BOX_LAYOUT (clutter_box_layout_get_type ())
|
||||||
|
#define CLUTTER_BOX_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayout))
|
||||||
|
#define CLUTTER_IS_BOX_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BOX_LAYOUT))
|
||||||
|
#define CLUTTER_BOX_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayoutClass))
|
||||||
|
#define CLUTTER_IS_BOX_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BOX_LAYOUT))
|
||||||
|
#define CLUTTER_BOX_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayoutClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterBoxLayout ClutterBoxLayout;
|
||||||
|
typedef struct _ClutterBoxLayoutPrivate ClutterBoxLayoutPrivate;
|
||||||
|
typedef struct _ClutterBoxLayoutClass ClutterBoxLayoutClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBoxAlignment:
|
||||||
|
* @CLUTTER_BOX_ALIGNMENT_START: Align the child to the top or to
|
||||||
|
* to the left, depending on the used axis
|
||||||
|
* @CLUTTER_BOX_ALIGNMENT_CENTER: Align the child to the center
|
||||||
|
* @CLUTTER_BOX_ALIGNMENT_END: Align the child to the bottom or to
|
||||||
|
* the right, depending on the used axis
|
||||||
|
*
|
||||||
|
* The alignment policies available on each axis of the #ClutterBoxLayout
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CLUTTER_BOX_ALIGNMENT_START,
|
||||||
|
CLUTTER_BOX_ALIGNMENT_END,
|
||||||
|
CLUTTER_BOX_ALIGNMENT_CENTER
|
||||||
|
} ClutterBoxAlignment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBoxLayout:
|
||||||
|
*
|
||||||
|
* The #ClutterBoxLayout structure contains only private data
|
||||||
|
* and should be accessed using the provided API
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _ClutterBoxLayout
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterLayoutManager parent_instance;
|
||||||
|
|
||||||
|
ClutterBoxLayoutPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBoxLayoutClass:
|
||||||
|
*
|
||||||
|
* The #ClutterBoxLayoutClass structure contains only private
|
||||||
|
* data and should be accessed using the provided API
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _ClutterBoxLayoutClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterLayoutManagerClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_box_layout_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterLayoutManager *clutter_box_layout_new (void);
|
||||||
|
|
||||||
|
void clutter_box_layout_set_spacing (ClutterBoxLayout *layout,
|
||||||
|
guint spacing);
|
||||||
|
guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout);
|
||||||
|
void clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
|
||||||
|
gboolean vertical);
|
||||||
|
gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout);
|
||||||
|
void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout,
|
||||||
|
gboolean pack_start);
|
||||||
|
gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout);
|
||||||
|
|
||||||
|
void clutter_box_layout_pack (ClutterBoxLayout *layout,
|
||||||
|
ClutterActor *actor,
|
||||||
|
gboolean expand,
|
||||||
|
gboolean x_fill,
|
||||||
|
gboolean y_fill,
|
||||||
|
ClutterBoxAlignment x_align,
|
||||||
|
ClutterBoxAlignment y_align);
|
||||||
|
void clutter_box_layout_set_alignment (ClutterBoxLayout *layout,
|
||||||
|
ClutterActor *actor,
|
||||||
|
ClutterBoxAlignment x_align,
|
||||||
|
ClutterBoxAlignment y_align);
|
||||||
|
void clutter_box_layout_get_alignment (ClutterBoxLayout *layout,
|
||||||
|
ClutterActor *actor,
|
||||||
|
ClutterBoxAlignment *x_align,
|
||||||
|
ClutterBoxAlignment *y_align);
|
||||||
|
void clutter_box_layout_set_fill (ClutterBoxLayout *layout,
|
||||||
|
ClutterActor *actor,
|
||||||
|
gboolean x_fill,
|
||||||
|
gboolean y_fill);
|
||||||
|
void clutter_box_layout_get_fill (ClutterBoxLayout *layout,
|
||||||
|
ClutterActor *actor,
|
||||||
|
gboolean *x_fill,
|
||||||
|
gboolean *y_fill);
|
||||||
|
void clutter_box_layout_set_expand (ClutterBoxLayout *layout,
|
||||||
|
ClutterActor *actor,
|
||||||
|
gboolean expand);
|
||||||
|
gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_BOX_LAYOUT_H__ */
|
828
clutter/clutter-box.c
Normal file
828
clutter/clutter-box.c
Normal file
@ -0,0 +1,828 @@
|
|||||||
|
/**
|
||||||
|
* SECTION:clutter-box
|
||||||
|
* @short_description: A Generic layout container
|
||||||
|
*
|
||||||
|
* #ClutterBox is a #ClutterActor sub-class implementing the #ClutterContainer
|
||||||
|
* interface. A Box delegates the whole size requisition and size allocation to
|
||||||
|
* a #ClutterLayoutManager instance.
|
||||||
|
*
|
||||||
|
* <example id="example-clutter-box">
|
||||||
|
* <title>Using ClutterBox</title>
|
||||||
|
* <para>The following code shows how to create a #ClutterBox with
|
||||||
|
* a #ClutterLayoutManager sub-class, and how to add children to
|
||||||
|
* it via clutter_box_pack().</para>
|
||||||
|
* <programlisting>
|
||||||
|
* ClutterActor *box;
|
||||||
|
* ClutterLayoutManager *layout;
|
||||||
|
*
|
||||||
|
* /* Create the layout manager first */
|
||||||
|
* layout = clutter_box_layout_new ();
|
||||||
|
* clutter_box_layout_set_homogeneous (CLUTTER_BOX_LAYOUT (layout), TRUE);
|
||||||
|
* clutter_box_layout_set_spacing (CLUTTER_BOX_LAYOUT (layout), 12);
|
||||||
|
*
|
||||||
|
* /* Then create the ClutterBox actor. The Box will take
|
||||||
|
* * ownership of the ClutterLayoutManager instance by sinking
|
||||||
|
* * its floating reference
|
||||||
|
* */
|
||||||
|
* box = clutter_box_new (layout);
|
||||||
|
*
|
||||||
|
* /* Now add children to the Box using the variadic arguments
|
||||||
|
* * function clutter_box_pack() to set layout properties
|
||||||
|
* */
|
||||||
|
* clutter_box_pack (CLUTTER_BOX (box), actor,
|
||||||
|
* "x-align", CLUTTER_BOX_ALIGNMENT_CENTER,
|
||||||
|
* "y-align", CLUTTER_BOX_ALIGNMENT_END,
|
||||||
|
* "expand", TRUE,
|
||||||
|
* NULL);
|
||||||
|
* </programlisting>
|
||||||
|
* </example>
|
||||||
|
*
|
||||||
|
* #ClutterBox<!-- -->'s clutter_box_pack() wraps the generic
|
||||||
|
* clutter_container_add_actor() function, but it also allows setting
|
||||||
|
* layout properties while adding the new child to the box.
|
||||||
|
*
|
||||||
|
* #ClutterBox is available since Clutter 1.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gobject/gvaluecollector.h>
|
||||||
|
|
||||||
|
#include "clutter-box.h"
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-enum-types.h"
|
||||||
|
#include "clutter-marshal.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
#define CLUTTER_BOX_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_BOX, ClutterBoxPrivate))
|
||||||
|
|
||||||
|
struct _ClutterBoxPrivate
|
||||||
|
{
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
|
||||||
|
GList *children;
|
||||||
|
|
||||||
|
guint changed_id;
|
||||||
|
|
||||||
|
ClutterColor color;
|
||||||
|
guint color_set : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_LAYOUT_MANAGER,
|
||||||
|
PROP_COLOR,
|
||||||
|
PROP_COLOR_SET
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ClutterColor default_box_color = { 255, 255, 255, 255 };
|
||||||
|
|
||||||
|
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (ClutterBox, clutter_box, CLUTTER_TYPE_ACTOR,
|
||||||
|
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTAINER,
|
||||||
|
clutter_container_iface_init));
|
||||||
|
|
||||||
|
static gint
|
||||||
|
sort_by_depth (gconstpointer a,
|
||||||
|
gconstpointer b)
|
||||||
|
{
|
||||||
|
gfloat depth_a = clutter_actor_get_depth ((ClutterActor *) a);
|
||||||
|
gfloat depth_b = clutter_actor_get_depth ((ClutterActor *) b);
|
||||||
|
|
||||||
|
if (depth_a < depth_b)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (depth_a > depth_b)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_add (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (container)->priv;
|
||||||
|
|
||||||
|
g_object_ref (actor);
|
||||||
|
|
||||||
|
priv->children = g_list_insert_sorted (priv->children,
|
||||||
|
actor,
|
||||||
|
sort_by_depth);
|
||||||
|
|
||||||
|
clutter_actor_set_parent (actor, CLUTTER_ACTOR (container));
|
||||||
|
|
||||||
|
clutter_layout_manager_add_child_meta (priv->manager,
|
||||||
|
container,
|
||||||
|
actor);
|
||||||
|
|
||||||
|
clutter_actor_queue_relayout (actor);
|
||||||
|
|
||||||
|
g_signal_emit_by_name (container, "actor-added", actor);
|
||||||
|
|
||||||
|
g_object_unref (actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_remove (ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (container)->priv;
|
||||||
|
|
||||||
|
g_object_ref (actor);
|
||||||
|
|
||||||
|
priv->children = g_list_remove (priv->children, actor);
|
||||||
|
clutter_actor_unparent (actor);
|
||||||
|
|
||||||
|
clutter_layout_manager_remove_child_meta (priv->manager,
|
||||||
|
container,
|
||||||
|
actor);
|
||||||
|
|
||||||
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (container));
|
||||||
|
|
||||||
|
g_signal_emit_by_name (container, "actor-removed", actor);
|
||||||
|
|
||||||
|
g_object_unref (actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_foreach (ClutterContainer *container,
|
||||||
|
ClutterCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (container)->priv;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = priv->children; l != NULL; l = l->next)
|
||||||
|
(* callback) (l->data, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_raise (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
ClutterActor *sibling)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (container)->priv;
|
||||||
|
|
||||||
|
priv->children = g_list_remove (priv->children, actor);
|
||||||
|
|
||||||
|
if (sibling == NULL)
|
||||||
|
priv->children = g_list_append (priv->children, actor);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gint index_ = g_list_index (priv->children, sibling) + 1;
|
||||||
|
|
||||||
|
priv->children = g_list_insert (priv->children, actor, index_);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (container));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_lower (ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
ClutterActor *sibling)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (container)->priv;
|
||||||
|
|
||||||
|
priv->children = g_list_remove (priv->children, actor);
|
||||||
|
|
||||||
|
if (sibling == NULL)
|
||||||
|
priv->children = g_list_prepend (priv->children, actor);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gint index_ = g_list_index (priv->children, sibling);
|
||||||
|
|
||||||
|
priv->children = g_list_insert (priv->children, actor, index_);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (container));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_sort_depth_order (ClutterContainer *container)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (container)->priv;
|
||||||
|
|
||||||
|
priv->children = g_list_sort (priv->children, sort_by_depth);
|
||||||
|
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (container));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_container_iface_init (ClutterContainerIface *iface)
|
||||||
|
{
|
||||||
|
iface->add = clutter_box_real_add;
|
||||||
|
iface->remove = clutter_box_real_remove;
|
||||||
|
iface->foreach = clutter_box_real_foreach;
|
||||||
|
iface->raise = clutter_box_real_raise;
|
||||||
|
iface->lower = clutter_box_real_lower;
|
||||||
|
iface->sort_depth_order = clutter_box_real_sort_depth_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_paint (ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (actor)->priv;
|
||||||
|
|
||||||
|
if (priv->color_set)
|
||||||
|
{
|
||||||
|
ClutterActorBox box = { 0, };
|
||||||
|
gfloat width, height;
|
||||||
|
guint8 tmp_alpha;
|
||||||
|
|
||||||
|
clutter_actor_get_allocation_box (actor, &box);
|
||||||
|
clutter_actor_box_get_size (&box, &width, &height);
|
||||||
|
|
||||||
|
tmp_alpha = clutter_actor_get_paint_opacity (actor)
|
||||||
|
* priv->color.alpha
|
||||||
|
/ 255;
|
||||||
|
|
||||||
|
cogl_set_source_color4ub (priv->color.red,
|
||||||
|
priv->color.green,
|
||||||
|
priv->color.blue,
|
||||||
|
tmp_alpha);
|
||||||
|
|
||||||
|
cogl_rectangle (0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_foreach (priv->children, (GFunc) clutter_actor_paint, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_pick (ClutterActor *actor,
|
||||||
|
const ClutterColor *pick)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (actor)->priv;
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (clutter_box_parent_class)->pick (actor, pick);
|
||||||
|
|
||||||
|
g_list_foreach (priv->children, (GFunc) clutter_actor_paint, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_get_preferred_width (ClutterActor *actor,
|
||||||
|
gfloat for_height,
|
||||||
|
gfloat *min_width,
|
||||||
|
gfloat *natural_width)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (actor)->priv;
|
||||||
|
|
||||||
|
/* if we don't have any children don't bother proxying the
|
||||||
|
* call to the layout manager instance
|
||||||
|
*/
|
||||||
|
if (priv->children == NULL)
|
||||||
|
{
|
||||||
|
if (min_width)
|
||||||
|
*min_width = 0.0;
|
||||||
|
|
||||||
|
if (natural_width)
|
||||||
|
*natural_width = 0.0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_layout_manager_get_preferred_width (priv->manager,
|
||||||
|
CLUTTER_CONTAINER (actor),
|
||||||
|
for_height,
|
||||||
|
min_width, natural_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_get_preferred_height (ClutterActor *actor,
|
||||||
|
gfloat for_width,
|
||||||
|
gfloat *min_height,
|
||||||
|
gfloat *natural_height)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (actor)->priv;
|
||||||
|
|
||||||
|
/* if we don't have any children don't bother proxying the
|
||||||
|
* call to the layout manager instance
|
||||||
|
*/
|
||||||
|
if (priv->children == NULL)
|
||||||
|
{
|
||||||
|
if (min_height)
|
||||||
|
*min_height = 0.0;
|
||||||
|
|
||||||
|
if (natural_height)
|
||||||
|
*natural_height = 0.0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_layout_manager_get_preferred_height (priv->manager,
|
||||||
|
CLUTTER_CONTAINER (actor),
|
||||||
|
for_width,
|
||||||
|
min_height, natural_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_real_allocate (ClutterActor *actor,
|
||||||
|
const ClutterActorBox *allocation,
|
||||||
|
ClutterAllocationFlags flags)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (actor)->priv;
|
||||||
|
ClutterActorClass *klass;
|
||||||
|
|
||||||
|
klass = CLUTTER_ACTOR_CLASS (clutter_box_parent_class);
|
||||||
|
klass->allocate (actor, allocation, flags);
|
||||||
|
|
||||||
|
if (priv->children == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
clutter_layout_manager_allocate (priv->manager,
|
||||||
|
CLUTTER_CONTAINER (actor),
|
||||||
|
allocation, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_destroy (ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (actor)->priv;
|
||||||
|
|
||||||
|
/* destroy all our children */
|
||||||
|
g_list_foreach (priv->children, (GFunc) clutter_actor_destroy, NULL);
|
||||||
|
|
||||||
|
CLUTTER_ACTOR_CLASS (clutter_box_parent_class)->destroy (actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_layout_manager (ClutterBox *self,
|
||||||
|
ClutterLayoutManager *manager)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->manager == manager)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (priv->manager != NULL)
|
||||||
|
{
|
||||||
|
if (priv->changed_id != 0)
|
||||||
|
g_signal_handler_disconnect (priv->manager, priv->changed_id);
|
||||||
|
|
||||||
|
clutter_layout_manager_set_container (priv->manager, NULL);
|
||||||
|
g_object_unref (priv->manager);
|
||||||
|
|
||||||
|
priv->manager = NULL;
|
||||||
|
priv->changed_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manager != NULL)
|
||||||
|
{
|
||||||
|
priv->manager = g_object_ref_sink (manager);
|
||||||
|
clutter_layout_manager_set_container (manager,
|
||||||
|
CLUTTER_CONTAINER (self));
|
||||||
|
|
||||||
|
priv->changed_id =
|
||||||
|
g_signal_connect_swapped (priv->manager, "layout-changed",
|
||||||
|
G_CALLBACK (clutter_actor_queue_relayout),
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (self), "layout-manager");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_dispose (GObject *gobject)
|
||||||
|
{
|
||||||
|
ClutterBox *self = CLUTTER_BOX (gobject);
|
||||||
|
|
||||||
|
set_layout_manager (self, NULL);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (clutter_box_parent_class)->dispose (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterBox *self = CLUTTER_BOX (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LAYOUT_MANAGER:
|
||||||
|
set_layout_manager (self, g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_COLOR:
|
||||||
|
clutter_box_set_color (self, clutter_value_get_color (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv = CLUTTER_BOX (gobject)->priv;
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_LAYOUT_MANAGER:
|
||||||
|
g_value_set_object (value, priv->manager);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_COLOR:
|
||||||
|
clutter_value_set_color (value, &priv->color);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_COLOR_SET:
|
||||||
|
g_value_set_boolean (value, priv->color_set);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_class_init (ClutterBoxClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (ClutterBoxPrivate));
|
||||||
|
|
||||||
|
actor_class->get_preferred_width = clutter_box_real_get_preferred_width;
|
||||||
|
actor_class->get_preferred_height = clutter_box_real_get_preferred_height;
|
||||||
|
actor_class->allocate = clutter_box_real_allocate;
|
||||||
|
actor_class->paint = clutter_box_real_paint;
|
||||||
|
actor_class->pick = clutter_box_real_pick;
|
||||||
|
actor_class->destroy = clutter_box_destroy;
|
||||||
|
|
||||||
|
gobject_class->set_property = clutter_box_set_property;
|
||||||
|
gobject_class->get_property = clutter_box_get_property;
|
||||||
|
gobject_class->dispose = clutter_box_dispose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBox:layout-manager:
|
||||||
|
*
|
||||||
|
* The #ClutterLayoutManager used by the #ClutterBox
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_object ("layout-manager",
|
||||||
|
"Layout Manager",
|
||||||
|
"The layout manager used by the box",
|
||||||
|
CLUTTER_TYPE_LAYOUT_MANAGER,
|
||||||
|
CLUTTER_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT);
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_LAYOUT_MANAGER,
|
||||||
|
pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBox:color:
|
||||||
|
*
|
||||||
|
* The color to be used to paint the background of the
|
||||||
|
* #ClutterBox. Setting this property will set the
|
||||||
|
* #ClutterBox:color-set property as a side effect
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
pspec = clutter_param_spec_color ("color",
|
||||||
|
"Color",
|
||||||
|
"The background color of the box",
|
||||||
|
&default_box_color,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_COLOR, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterBox:color-set:
|
||||||
|
*
|
||||||
|
* Whether the #ClutterBox:color property has been set
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_boolean ("color-set",
|
||||||
|
"Color Set",
|
||||||
|
"Whether the background color is set",
|
||||||
|
FALSE,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_COLOR_SET, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_box_init (ClutterBox *self)
|
||||||
|
{
|
||||||
|
self->priv = CLUTTER_BOX_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
self->priv->color = default_box_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_box_new:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
*
|
||||||
|
* Creates a new #ClutterBox. The children of the box will be layed
|
||||||
|
* out by the passed @manager
|
||||||
|
*
|
||||||
|
* Return value: the newly created #ClutterBox actor
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
ClutterActor *
|
||||||
|
clutter_box_new (ClutterLayoutManager *manager)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), NULL);
|
||||||
|
|
||||||
|
return g_object_new (CLUTTER_TYPE_BOX,
|
||||||
|
"layout-manager", manager,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_box_set_layout_manager:
|
||||||
|
* @box: a #ClutterBox
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
*
|
||||||
|
* Sets the #ClutterLayoutManager for @box
|
||||||
|
*
|
||||||
|
* A #ClutterLayoutManager is a delegate object that controls the
|
||||||
|
* layout of the children of @box
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_box_set_layout_manager (ClutterBox *box,
|
||||||
|
ClutterLayoutManager *manager)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_BOX (box));
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
|
||||||
|
set_layout_manager (box, manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_box_get_layout_manager:
|
||||||
|
* @box: a #ClutterBox
|
||||||
|
*
|
||||||
|
* Retrieves the #ClutterLayoutManager instance used by @box
|
||||||
|
*
|
||||||
|
* Return value: a #ClutterLayoutManager
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
ClutterLayoutManager *
|
||||||
|
clutter_box_get_layout_manager (ClutterBox *box)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_BOX (box), NULL);
|
||||||
|
|
||||||
|
return box->priv->manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_box_packv:
|
||||||
|
* @box: a #ClutterBox
|
||||||
|
* @actor: a #ClutterActor
|
||||||
|
* @n_properties: the number of properties to set
|
||||||
|
* @properties: (array length=n_properties) (element-type utf8): a vector
|
||||||
|
* containing the property names to set
|
||||||
|
* @values: (array length=n_properties): a vector containing the property
|
||||||
|
* values to set
|
||||||
|
*
|
||||||
|
* Vector-based variant of clutter_box_pack(), intended for language
|
||||||
|
* bindings to use
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_box_packv (ClutterBox *box,
|
||||||
|
ClutterActor *actor,
|
||||||
|
guint n_properties,
|
||||||
|
const gchar * const properties[],
|
||||||
|
const GValue *values)
|
||||||
|
{
|
||||||
|
ClutterContainer *container;
|
||||||
|
ClutterBoxPrivate *priv;
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
GObjectClass *klass;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_BOX (box));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
|
||||||
|
container = CLUTTER_CONTAINER (box);
|
||||||
|
clutter_container_add_actor (container, actor);
|
||||||
|
|
||||||
|
priv = box->priv;
|
||||||
|
|
||||||
|
meta = clutter_layout_manager_get_child_meta (priv->manager,
|
||||||
|
container,
|
||||||
|
actor);
|
||||||
|
|
||||||
|
if (meta == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (meta);
|
||||||
|
|
||||||
|
for (i = 0; i < n_properties; i++)
|
||||||
|
{
|
||||||
|
const gchar *pname = properties[i];
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
pspec = g_object_class_find_property (klass, pname);
|
||||||
|
if (pspec == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("%s: the layout property '%s' for managers "
|
||||||
|
"of type '%s' (meta type '%s') does not exist",
|
||||||
|
G_STRLOC,
|
||||||
|
pname,
|
||||||
|
G_OBJECT_TYPE_NAME (priv->manager),
|
||||||
|
G_OBJECT_TYPE_NAME (meta));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||||
|
{
|
||||||
|
g_warning ("%s: the layout property '%s' for managers "
|
||||||
|
"of type '%s' (meta type '%s') is not writable",
|
||||||
|
G_STRLOC,
|
||||||
|
pspec->name,
|
||||||
|
G_OBJECT_TYPE_NAME (priv->manager),
|
||||||
|
G_OBJECT_TYPE_NAME (meta));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_layout_manager_child_set_property (priv->manager,
|
||||||
|
container, actor,
|
||||||
|
pname, &values[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_box_pack:
|
||||||
|
* @box: a #ClutterBox
|
||||||
|
* @actor: a #ClutterActor
|
||||||
|
* @first_property: the name of the first property to set, or %NULL
|
||||||
|
* @Varargs: a list of property name and value pairs, terminated by %NULL
|
||||||
|
*
|
||||||
|
* Adds @actor to @box and sets layout properties at the same time,
|
||||||
|
* if the #ClutterLayoutManager used by @box has them
|
||||||
|
*
|
||||||
|
* This function is a wrapper around clutter_container_add_actor()
|
||||||
|
* and clutter_layout_manager_child_set()
|
||||||
|
*
|
||||||
|
* Language bindings should use the vector-based clutter_box_addv()
|
||||||
|
* variant instead
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_box_pack (ClutterBox *box,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_property,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv;
|
||||||
|
ClutterContainer *container;
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
GObjectClass *klass;
|
||||||
|
const gchar *pname;
|
||||||
|
va_list var_args;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_BOX (box));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
|
||||||
|
container = CLUTTER_CONTAINER (box);
|
||||||
|
clutter_container_add_actor (container, actor);
|
||||||
|
|
||||||
|
if (first_property == NULL || *first_property == '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv = box->priv;
|
||||||
|
|
||||||
|
meta = clutter_layout_manager_get_child_meta (priv->manager,
|
||||||
|
container,
|
||||||
|
actor);
|
||||||
|
|
||||||
|
if (meta == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (meta);
|
||||||
|
|
||||||
|
va_start (var_args, first_property);
|
||||||
|
|
||||||
|
pname = first_property;
|
||||||
|
while (pname)
|
||||||
|
{
|
||||||
|
GValue value = { 0, };
|
||||||
|
GParamSpec *pspec;
|
||||||
|
gchar *error;
|
||||||
|
|
||||||
|
pspec = g_object_class_find_property (klass, pname);
|
||||||
|
if (pspec == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("%s: the layout property '%s' for managers "
|
||||||
|
"of type '%s' (meta type '%s') does not exist",
|
||||||
|
G_STRLOC,
|
||||||
|
pname,
|
||||||
|
G_OBJECT_TYPE_NAME (priv->manager),
|
||||||
|
G_OBJECT_TYPE_NAME (meta));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||||
|
{
|
||||||
|
g_warning ("%s: the layout property '%s' for managers "
|
||||||
|
"of type '%s' (meta type '%s') is not writable",
|
||||||
|
G_STRLOC,
|
||||||
|
pspec->name,
|
||||||
|
G_OBJECT_TYPE_NAME (priv->manager),
|
||||||
|
G_OBJECT_TYPE_NAME (meta));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
G_VALUE_COLLECT (&value, var_args, 0, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error);
|
||||||
|
g_free (error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_layout_manager_child_set_property (priv->manager,
|
||||||
|
container, actor,
|
||||||
|
pspec->name, &value);
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
pname = va_arg (var_args, gchar*);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end (var_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_box_set_color:
|
||||||
|
* @box: a #ClutterBox
|
||||||
|
* @color: (allow-none): the background color, or %NULL to unset
|
||||||
|
*
|
||||||
|
* Sets (or unsets) the background color for @box
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_box_set_color (ClutterBox *box,
|
||||||
|
const ClutterColor *color)
|
||||||
|
{
|
||||||
|
ClutterBoxPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_BOX (box));
|
||||||
|
|
||||||
|
priv = box->priv;
|
||||||
|
|
||||||
|
if (color)
|
||||||
|
{
|
||||||
|
priv->color = *color;
|
||||||
|
priv->color_set = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
priv->color_set = FALSE;
|
||||||
|
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (box));
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (box), "color-set");
|
||||||
|
g_object_notify (G_OBJECT (box), "color");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_box_get_color:
|
||||||
|
* @box: a #ClutterBox
|
||||||
|
* @color: (out): return location for a #ClutterColor
|
||||||
|
*
|
||||||
|
* Retrieves the background color of @box
|
||||||
|
*
|
||||||
|
* If the #ClutterBox:color-set property is set to %FALSE the
|
||||||
|
* returned #ClutterColor is undefined
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_box_get_color (ClutterBox *box,
|
||||||
|
ClutterColor *color)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_BOX (box));
|
||||||
|
g_return_if_fail (color != NULL);
|
||||||
|
|
||||||
|
*color = box->priv->color;
|
||||||
|
}
|
62
clutter/clutter-box.h
Normal file
62
clutter/clutter-box.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||||
|
#error "Only <clutter/clutter.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CLUTTER_BOX_H__
|
||||||
|
#define __CLUTTER_BOX_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-actor.h>
|
||||||
|
#include <clutter/clutter-container.h>
|
||||||
|
#include <clutter/clutter-layout-manager.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_BOX (clutter_box_get_type ())
|
||||||
|
#define CLUTTER_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BOX, ClutterBox))
|
||||||
|
#define CLUTTER_IS_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BOX))
|
||||||
|
#define CLUTTER_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BOX, ClutterBoxClass))
|
||||||
|
#define CLUTTER_IS_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BOX))
|
||||||
|
#define CLUTTER_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BOX, ClutterBoxClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterBox ClutterBox;
|
||||||
|
typedef struct _ClutterBoxPrivate ClutterBoxPrivate;
|
||||||
|
typedef struct _ClutterBoxClass ClutterBoxClass;
|
||||||
|
|
||||||
|
struct _ClutterBox
|
||||||
|
{
|
||||||
|
ClutterActor parent_instance;
|
||||||
|
|
||||||
|
ClutterBoxPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ClutterBoxClass
|
||||||
|
{
|
||||||
|
ClutterActorClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_box_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterActor * clutter_box_new (ClutterLayoutManager *manager);
|
||||||
|
|
||||||
|
void clutter_box_set_layout_manager (ClutterBox *box,
|
||||||
|
ClutterLayoutManager *manager);
|
||||||
|
ClutterLayoutManager *clutter_box_get_layout_manager (ClutterBox *box);
|
||||||
|
|
||||||
|
void clutter_box_set_color (ClutterBox *box,
|
||||||
|
const ClutterColor *color);
|
||||||
|
void clutter_box_get_color (ClutterBox *box,
|
||||||
|
ClutterColor *color);
|
||||||
|
|
||||||
|
void clutter_box_pack (ClutterBox *box,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_property,
|
||||||
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
void clutter_box_packv (ClutterBox *box,
|
||||||
|
ClutterActor *actor,
|
||||||
|
guint n_properties,
|
||||||
|
const gchar * const properties[],
|
||||||
|
const GValue *values);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_BOX_H__ */
|
186
clutter/clutter-fixed-layout.c
Normal file
186
clutter/clutter-fixed-layout.c
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
*
|
||||||
|
* Based on the fixed layout code inside clutter-group.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:clutter-fixed-layout
|
||||||
|
* @short_description: A fixed layout manager
|
||||||
|
*
|
||||||
|
* #ClutterFixedLayout is a layout manager implementing the same
|
||||||
|
* layout policies as #ClutterGroup.
|
||||||
|
*
|
||||||
|
* #ClutterFixedLayout is available since Clutter 1.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-fixed-layout.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ClutterFixedLayout,
|
||||||
|
clutter_fixed_layout,
|
||||||
|
CLUTTER_TYPE_LAYOUT_MANAGER);
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_fixed_layout_get_preferred_width (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_height,
|
||||||
|
gfloat *min_width_p,
|
||||||
|
gfloat *nat_width_p)
|
||||||
|
{
|
||||||
|
GList *children, *l;
|
||||||
|
gdouble min_right;
|
||||||
|
gdouble natural_right;
|
||||||
|
|
||||||
|
min_right = 0;
|
||||||
|
natural_right = 0;
|
||||||
|
|
||||||
|
children = clutter_container_get_children (container);
|
||||||
|
|
||||||
|
for (l = children; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
ClutterActor *child = l->data;
|
||||||
|
gfloat child_x, child_min, child_natural;
|
||||||
|
|
||||||
|
child_x = clutter_actor_get_x (child);
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_size (child,
|
||||||
|
&child_min, NULL,
|
||||||
|
&child_natural, NULL);
|
||||||
|
|
||||||
|
if (child_x + child_min > min_right)
|
||||||
|
min_right = child_x + child_min;
|
||||||
|
|
||||||
|
if (child_x + child_natural > natural_right)
|
||||||
|
natural_right = child_x + child_natural;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (children);
|
||||||
|
|
||||||
|
if (min_width_p)
|
||||||
|
*min_width_p = min_right;
|
||||||
|
|
||||||
|
if (nat_width_p)
|
||||||
|
*nat_width_p = natural_right;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_fixed_layout_get_preferred_height (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_width,
|
||||||
|
gfloat *min_height_p,
|
||||||
|
gfloat *nat_height_p)
|
||||||
|
{
|
||||||
|
GList *children, *l;
|
||||||
|
gdouble min_bottom;
|
||||||
|
gdouble natural_bottom;
|
||||||
|
|
||||||
|
min_bottom = 0;
|
||||||
|
natural_bottom = 0;
|
||||||
|
|
||||||
|
children = clutter_container_get_children (container);
|
||||||
|
|
||||||
|
for (l = children; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
ClutterActor *child = l->data;
|
||||||
|
gfloat child_y, child_min, child_natural;
|
||||||
|
|
||||||
|
child_y = clutter_actor_get_y (child);
|
||||||
|
|
||||||
|
clutter_actor_get_preferred_size (child,
|
||||||
|
NULL, &child_min,
|
||||||
|
NULL, &child_natural);
|
||||||
|
|
||||||
|
if (child_y + child_min > min_bottom)
|
||||||
|
min_bottom = child_y + child_min;
|
||||||
|
|
||||||
|
if (child_y + child_natural > natural_bottom)
|
||||||
|
natural_bottom = child_y + child_natural;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (children);
|
||||||
|
|
||||||
|
if (min_height_p)
|
||||||
|
*min_height_p = min_bottom;
|
||||||
|
|
||||||
|
if (nat_height_p)
|
||||||
|
*nat_height_p = natural_bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_fixed_layout_allocate (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
const ClutterActorBox *allocation,
|
||||||
|
ClutterAllocationFlags flags)
|
||||||
|
{
|
||||||
|
GList *children, *l;
|
||||||
|
|
||||||
|
children = clutter_container_get_children (container);
|
||||||
|
|
||||||
|
for (l = children; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
ClutterActor *child = l->data;
|
||||||
|
|
||||||
|
clutter_actor_allocate_preferred_size (child, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (children);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_fixed_layout_class_init (ClutterFixedLayoutClass *klass)
|
||||||
|
{
|
||||||
|
ClutterLayoutManagerClass *manager_class =
|
||||||
|
CLUTTER_LAYOUT_MANAGER_CLASS (klass);
|
||||||
|
|
||||||
|
manager_class->get_preferred_width =
|
||||||
|
clutter_fixed_layout_get_preferred_width;
|
||||||
|
manager_class->get_preferred_height =
|
||||||
|
clutter_fixed_layout_get_preferred_height;
|
||||||
|
manager_class->allocate = clutter_fixed_layout_allocate;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_fixed_layout_init (ClutterFixedLayout *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_fixed_layout_new:
|
||||||
|
*
|
||||||
|
* Creates a new #ClutterFixedLayout
|
||||||
|
*
|
||||||
|
* Return value: the newly created #ClutterFixedLayout
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
ClutterLayoutManager *
|
||||||
|
clutter_fixed_layout_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (CLUTTER_TYPE_FIXED_LAYOUT, NULL);
|
||||||
|
}
|
80
clutter/clutter-fixed-layout.h
Normal file
80
clutter/clutter-fixed-layout.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* 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_FIXED_LAYOUT_H__
|
||||||
|
#define __CLUTTER_FIXED_LAYOUT_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-layout-manager.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_FIXED_LAYOUT (clutter_fixed_layout_get_type ())
|
||||||
|
#define CLUTTER_FIXED_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_FIXED_LAYOUT, ClutterFixedLayout))
|
||||||
|
#define CLUTTER_IS_FIXED_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_FIXED_LAYOUT))
|
||||||
|
#define CLUTTER_FIXED_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_FIXED_LAYOUT, ClutterFixedLayoutClass))
|
||||||
|
#define CLUTTER_IS_FIXED_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_FIXED_LAYOUT))
|
||||||
|
#define CLUTTER_FIXED_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_FIXED_LAYOUT, ClutterFixedLayoutClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterFixedLayout ClutterFixedLayout;
|
||||||
|
typedef struct _ClutterFixedLayoutClass ClutterFixedLayoutClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterFixedLayout:
|
||||||
|
*
|
||||||
|
* The #ClutterFixedLayout structure contains only private data and
|
||||||
|
* it should be accessed using the provided API
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _ClutterFixedLayout
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterLayoutManager parent_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterFixedLayoutClass:
|
||||||
|
*
|
||||||
|
* The #ClutterFixedLayoutClass structure contains only private data
|
||||||
|
* and it should be accessed using the provided API
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _ClutterFixedLayoutClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterLayoutManagerClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_fixed_layout_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterLayoutManager *clutter_fixed_layout_new (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_FIXED_LAYOUT_H__ */
|
1321
clutter/clutter-flow-layout.c
Normal file
1321
clutter/clutter-flow-layout.c
Normal file
File diff suppressed because it is too large
Load Diff
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_homogeneous (ClutterFlowLayout *layout,
|
||||||
|
gboolean homogeneous);
|
||||||
|
gboolean clutter_flow_layout_get_homogeneous (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__ */
|
@ -45,6 +45,7 @@
|
|||||||
#include "clutter-group.h"
|
#include "clutter-group.h"
|
||||||
|
|
||||||
#include "clutter-container.h"
|
#include "clutter-container.h"
|
||||||
|
#include "clutter-fixed-layout.h"
|
||||||
#include "clutter-main.h"
|
#include "clutter-main.h"
|
||||||
#include "clutter-private.h"
|
#include "clutter-private.h"
|
||||||
#include "clutter-debug.h"
|
#include "clutter-debug.h"
|
||||||
@ -75,6 +76,8 @@ G_DEFINE_TYPE_WITH_CODE (ClutterGroup,
|
|||||||
struct _ClutterGroupPrivate
|
struct _ClutterGroupPrivate
|
||||||
{
|
{
|
||||||
GList *children;
|
GList *children;
|
||||||
|
|
||||||
|
ClutterLayoutManager *layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -126,111 +129,17 @@ clutter_group_pick (ClutterActor *actor,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
clutter_fixed_layout_get_preferred_width (GList *children,
|
|
||||||
gfloat *min_width_p,
|
|
||||||
gfloat *natural_width_p)
|
|
||||||
{
|
|
||||||
GList *l;
|
|
||||||
gdouble min_right, natural_right;
|
|
||||||
|
|
||||||
/* We will always be at least 0 sized (ie, if all of the actors are
|
|
||||||
to the left of the origin we won't return a negative size) */
|
|
||||||
min_right = 0;
|
|
||||||
natural_right = 0;
|
|
||||||
|
|
||||||
for (l = children; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
ClutterActor *child = l->data;
|
|
||||||
gfloat child_x, child_min, child_natural;
|
|
||||||
|
|
||||||
child_x = clutter_actor_get_x (child);
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_size (child,
|
|
||||||
&child_min, NULL,
|
|
||||||
&child_natural, NULL);
|
|
||||||
|
|
||||||
/* Track the rightmost edge */
|
|
||||||
if (child_x + child_min > min_right)
|
|
||||||
min_right = child_x + child_min;
|
|
||||||
|
|
||||||
if (child_x + child_natural > natural_right)
|
|
||||||
natural_right = child_x + child_natural;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The size is defined as the distance from the origin to the
|
|
||||||
right-hand edge of the rightmost actor */
|
|
||||||
if (min_width_p)
|
|
||||||
*min_width_p = min_right;
|
|
||||||
|
|
||||||
if (natural_width_p)
|
|
||||||
*natural_width_p = natural_right;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
clutter_fixed_layout_get_preferred_height (GList *children,
|
|
||||||
gfloat *min_height_p,
|
|
||||||
gfloat *natural_height_p)
|
|
||||||
{
|
|
||||||
GList *l;
|
|
||||||
gdouble min_bottom, natural_bottom;
|
|
||||||
|
|
||||||
/* We will always be at least 0 sized (ie, if all of the actors are
|
|
||||||
above the origin we won't return a negative size) */
|
|
||||||
min_bottom = 0;
|
|
||||||
natural_bottom = 0;
|
|
||||||
|
|
||||||
for (l = children; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
ClutterActor *child = l->data;
|
|
||||||
gfloat child_y, child_min, child_natural;
|
|
||||||
|
|
||||||
child_y = clutter_actor_get_y (child);
|
|
||||||
|
|
||||||
clutter_actor_get_preferred_size (child,
|
|
||||||
NULL, &child_min,
|
|
||||||
NULL, &child_natural);
|
|
||||||
|
|
||||||
/* Track the bottommost edge */
|
|
||||||
if (child_y + child_min > min_bottom)
|
|
||||||
min_bottom = child_y + child_min;
|
|
||||||
|
|
||||||
if (child_y + child_natural > natural_bottom)
|
|
||||||
natural_bottom = child_y + child_natural;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The size is defined as the distance from the origin to the bottom
|
|
||||||
edge of the bottommost actor */
|
|
||||||
if (min_height_p)
|
|
||||||
*min_height_p = min_bottom;
|
|
||||||
|
|
||||||
if (natural_height_p)
|
|
||||||
*natural_height_p = natural_bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
clutter_fixed_layout_allocate (GList *children,
|
|
||||||
ClutterAllocationFlags flags)
|
|
||||||
{
|
|
||||||
GList *l;
|
|
||||||
|
|
||||||
for (l = children; l != NULL; l = l->next)
|
|
||||||
{
|
|
||||||
ClutterActor *child = l->data;
|
|
||||||
clutter_actor_allocate_preferred_size (child, flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_group_get_preferred_width (ClutterActor *self,
|
clutter_group_get_preferred_width (ClutterActor *self,
|
||||||
gfloat for_height,
|
gfloat for_height,
|
||||||
gfloat *min_width_p,
|
gfloat *min_width_p,
|
||||||
gfloat *natural_width_p)
|
gfloat *natural_width_p)
|
||||||
{
|
{
|
||||||
|
ClutterContainer *container = CLUTTER_CONTAINER (self);
|
||||||
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
||||||
|
|
||||||
/* for_height is irrelevant to the fixed layout, so it's not used */
|
clutter_layout_manager_get_preferred_width (priv->layout, container,
|
||||||
clutter_fixed_layout_get_preferred_width (priv->children,
|
for_height,
|
||||||
min_width_p,
|
min_width_p,
|
||||||
natural_width_p);
|
natural_width_p);
|
||||||
}
|
}
|
||||||
@ -241,10 +150,11 @@ clutter_group_get_preferred_height (ClutterActor *self,
|
|||||||
gfloat *min_height_p,
|
gfloat *min_height_p,
|
||||||
gfloat *natural_height_p)
|
gfloat *natural_height_p)
|
||||||
{
|
{
|
||||||
|
ClutterContainer *container = CLUTTER_CONTAINER (self);
|
||||||
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
||||||
|
|
||||||
/* for_width is irrelevant to the fixed layout, so it's not used */
|
clutter_layout_manager_get_preferred_width (priv->layout, container,
|
||||||
clutter_fixed_layout_get_preferred_height (priv->children,
|
for_width,
|
||||||
min_height_p,
|
min_height_p,
|
||||||
natural_height_p);
|
natural_height_p);
|
||||||
}
|
}
|
||||||
@ -254,17 +164,16 @@ clutter_group_allocate (ClutterActor *self,
|
|||||||
const ClutterActorBox *box,
|
const ClutterActorBox *box,
|
||||||
ClutterAllocationFlags flags)
|
ClutterAllocationFlags flags)
|
||||||
{
|
{
|
||||||
|
ClutterContainer *container = CLUTTER_CONTAINER (self);
|
||||||
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
ClutterGroupPrivate *priv = CLUTTER_GROUP (self)->priv;
|
||||||
|
|
||||||
/* chain up to set actor->allocation */
|
/* chain up to set actor->allocation */
|
||||||
CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->allocate (self, box, flags);
|
CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->allocate (self, box, flags);
|
||||||
|
|
||||||
/* Note that fixed-layout allocation of children does not care what
|
if (priv->children == NULL)
|
||||||
* allocation the container received, so "box" is not passed in
|
return;
|
||||||
* here. We do not require that children's allocations are completely
|
|
||||||
* contained by our own.
|
clutter_layout_manager_allocate (priv->layout, container, box, flags);
|
||||||
*/
|
|
||||||
clutter_fixed_layout_allocate (priv->children, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -281,6 +190,12 @@ clutter_group_dispose (GObject *object)
|
|||||||
priv->children = NULL;
|
priv->children = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->layout)
|
||||||
|
{
|
||||||
|
g_object_unref (priv->layout);
|
||||||
|
priv->layout = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (clutter_group_parent_class)->dispose (object);
|
G_OBJECT_CLASS (clutter_group_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,8 +383,10 @@ sort_z_order (gconstpointer a,
|
|||||||
|
|
||||||
if (depth_a < depth_b)
|
if (depth_a < depth_b)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (depth_a > depth_b)
|
if (depth_a > depth_b)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,6 +438,9 @@ static void
|
|||||||
clutter_group_init (ClutterGroup *self)
|
clutter_group_init (ClutterGroup *self)
|
||||||
{
|
{
|
||||||
self->priv = CLUTTER_GROUP_GET_PRIVATE (self);
|
self->priv = CLUTTER_GROUP_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
self->priv->layout = clutter_fixed_layout_new ();
|
||||||
|
g_object_ref_sink (self->priv->layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
887
clutter/clutter-layout-manager.c
Normal file
887
clutter/clutter-layout-manager.c
Normal file
@ -0,0 +1,887 @@
|
|||||||
|
/*
|
||||||
|
* 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-layout-manager
|
||||||
|
* @short_description: Layout managers base class
|
||||||
|
*
|
||||||
|
* #ClutterLayoutManager is a base abstract class for layout managers. A
|
||||||
|
* layout manager implements the layouting policy for a composite or a
|
||||||
|
* container actor: it controls the preferred size of the actor to which
|
||||||
|
* it has been paired, and it controls the allocation of its children.
|
||||||
|
*
|
||||||
|
* Any composite or container #ClutterActor subclass can delegate the
|
||||||
|
* layouting of its children to a #ClutterLayoutManager. Clutter provides
|
||||||
|
* a generic container using #ClutterLayoutManager called #ClutterBox.
|
||||||
|
*
|
||||||
|
* Clutter provides some simple #ClutterLayoutManager sub-classes, like
|
||||||
|
* #ClutterFixedLayout and #ClutterBinLayout.
|
||||||
|
*
|
||||||
|
* <refsect2 id="ClutterLayoutManager-use-in-Actor">
|
||||||
|
* <title>Using ClutterLayoutManager inside an Actor</title>
|
||||||
|
* <para>In order to use a #ClutterLayoutManager inside a #ClutterActor
|
||||||
|
* sub-class you should invoke clutter_layout_manager_get_preferred_width()
|
||||||
|
* inside the <structname>ClutterActor</structname>::get_preferred_width()
|
||||||
|
* virtual function and clutter_layout_manager_get_preferred_height()
|
||||||
|
* inside the <structname>ClutterActor</structname>::get_preferred_height()
|
||||||
|
* virtual function implementations. You should also call
|
||||||
|
* clutter_layout_manager_allocate() inside the implementation of the
|
||||||
|
* <structname>ClutterActor</structname>::allocate() virtual
|
||||||
|
* function.</para>
|
||||||
|
* <para>In order to receive notifications for changes in the layout
|
||||||
|
* manager policies you should also connect to the
|
||||||
|
* #ClutterLayoutManager::layout-changed signal and queue a relayout
|
||||||
|
* on your actor. The following code should be enough if the actor
|
||||||
|
* does not need to perform specific operations whenever a layout
|
||||||
|
* manager changes:</para>
|
||||||
|
* <informalexample><programlisting>
|
||||||
|
* g_signal_connect_swapped (layout_manager,
|
||||||
|
* "layout-changed",
|
||||||
|
* G_CALLBACK (clutter_actor_queue_relayout),
|
||||||
|
* actor);
|
||||||
|
* </programlisting></informalexample>
|
||||||
|
* </refsect2>
|
||||||
|
*
|
||||||
|
* <refsect2 id="ClutterLayoutManager-implementation">
|
||||||
|
* <title>Implementing a ClutterLayoutManager</title>
|
||||||
|
* <para>The implementation of a layout manager does not differ from
|
||||||
|
* the implementation of the size requisition and allocation bits of
|
||||||
|
* #ClutterActor, so you should read the relative documentation
|
||||||
|
* <link linkend="clutter-subclassing-ClutterActor">for subclassing
|
||||||
|
* ClutterActor</link>.</para>
|
||||||
|
* <para>The layout manager implementation can hold a back reference
|
||||||
|
* to the #ClutterContainer by implementing the set_container()
|
||||||
|
* virtual function. The layout manager should not hold a reference
|
||||||
|
* on the container actor, to avoid reference cycles.</para>
|
||||||
|
* <para>If the layout manager has properties affecting the layout
|
||||||
|
* policies then it should emit the #ClutterLayoutManager::layout-changed
|
||||||
|
* signal on itself by using the clutter_layout_manager_layout_changed()
|
||||||
|
* function.</para>
|
||||||
|
* </refsect2>
|
||||||
|
*
|
||||||
|
* #ClutterLayoutManager is available since Clutter 1.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gobject/gvaluecollector.h>
|
||||||
|
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-layout-manager.h"
|
||||||
|
#include "clutter-layout-meta.h"
|
||||||
|
#include "clutter-marshal.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
#define LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED(m,method) G_STMT_START { \
|
||||||
|
GObject *_obj = G_OBJECT (m); \
|
||||||
|
g_warning ("Layout managers of type %s do not implement " \
|
||||||
|
"the ClutterLayoutManager::%s method", \
|
||||||
|
G_OBJECT_TYPE_NAME (_obj), \
|
||||||
|
(method)); } G_STMT_END
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
LAYOUT_CHANGED,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_ABSTRACT_TYPE (ClutterLayoutManager,
|
||||||
|
clutter_layout_manager,
|
||||||
|
G_TYPE_INITIALLY_UNOWNED);
|
||||||
|
|
||||||
|
static GQuark quark_layout_meta = 0;
|
||||||
|
static guint manager_signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
static void
|
||||||
|
layout_manager_real_get_preferred_width (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_height,
|
||||||
|
gfloat *min_width_p,
|
||||||
|
gfloat *nat_width_p)
|
||||||
|
{
|
||||||
|
LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, "get_preferred_width");
|
||||||
|
|
||||||
|
if (min_width_p)
|
||||||
|
*min_width_p = 0.0;
|
||||||
|
|
||||||
|
if (nat_width_p)
|
||||||
|
*nat_width_p = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
layout_manager_real_get_preferred_height (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_width,
|
||||||
|
gfloat *min_height_p,
|
||||||
|
gfloat *nat_height_p)
|
||||||
|
{
|
||||||
|
LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, "get_preferred_height");
|
||||||
|
|
||||||
|
if (min_height_p)
|
||||||
|
*min_height_p = 0.0;
|
||||||
|
|
||||||
|
if (nat_height_p)
|
||||||
|
*nat_height_p = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
layout_manager_real_allocate (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
const ClutterActorBox *allocation,
|
||||||
|
ClutterAllocationFlags flags)
|
||||||
|
{
|
||||||
|
LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, "allocate");
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClutterLayoutMeta *
|
||||||
|
layout_manager_real_create_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_layout_manager_class_init (ClutterLayoutManagerClass *klass)
|
||||||
|
{
|
||||||
|
quark_layout_meta =
|
||||||
|
g_quark_from_static_string ("clutter-layout-manager-child-meta");
|
||||||
|
|
||||||
|
klass->get_preferred_width = layout_manager_real_get_preferred_width;
|
||||||
|
klass->get_preferred_height = layout_manager_real_get_preferred_height;
|
||||||
|
klass->allocate = layout_manager_real_allocate;
|
||||||
|
klass->create_child_meta = layout_manager_real_create_child_meta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterLayoutManager::layout-changed:
|
||||||
|
* @manager: the #ClutterLayoutManager that emitted the signal
|
||||||
|
*
|
||||||
|
* The ::layout-changed signal is emitted each time a layout manager
|
||||||
|
* has been changed. Every #ClutterActor using the @manager instance
|
||||||
|
* as a layout manager should connect a handler to the ::layout-changed
|
||||||
|
* signal and queue a relayout on themselves:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* static void layout_changed (ClutterLayoutManager *manager,
|
||||||
|
* ClutterActor *self)
|
||||||
|
* {
|
||||||
|
* clutter_actor_queue_relayout (self);
|
||||||
|
* }
|
||||||
|
* ...
|
||||||
|
* self->manager = g_object_ref_sink (manager);
|
||||||
|
* g_signal_connect (self->manager, "layout-changed",
|
||||||
|
* G_CALLBACK (layout_changed),
|
||||||
|
* self);
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* Sub-classes of #ClutterLayoutManager that implement a layout that
|
||||||
|
* can be controlled or changed using parameters should emit the
|
||||||
|
* ::layout-changed signal whenever one of the parameters changes,
|
||||||
|
* by using clutter_layout_manager_layout_changed().
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
manager_signals[LAYOUT_CHANGED] =
|
||||||
|
g_signal_new (I_("layout-changed"),
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (ClutterLayoutManagerClass,
|
||||||
|
layout_changed),
|
||||||
|
NULL, NULL,
|
||||||
|
clutter_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_layout_manager_init (ClutterLayoutManager *manager)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_get_preferred_width:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: the #ClutterContainer using @manager
|
||||||
|
* @for_height: the height for which the width should be computed, or -1
|
||||||
|
* @min_width_p: (out) (allow-none): return location for the minimum width
|
||||||
|
* of the layout, or %NULL
|
||||||
|
* @nat_width_p: (out) (allow-none): return location for the natural width
|
||||||
|
* of the layout, or %NULL
|
||||||
|
*
|
||||||
|
* Computes the minimum and natural widths of the @container according
|
||||||
|
* to @manager.
|
||||||
|
*
|
||||||
|
* See also clutter_actor_get_preferred_width()
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_get_preferred_width (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_height,
|
||||||
|
gfloat *min_width_p,
|
||||||
|
gfloat *nat_width_p)
|
||||||
|
{
|
||||||
|
ClutterLayoutManagerClass *klass;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
|
||||||
|
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
|
||||||
|
klass->get_preferred_width (manager, container, for_height,
|
||||||
|
min_width_p,
|
||||||
|
nat_width_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_get_preferred_height:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: the #ClutterContainer using @manager
|
||||||
|
* @for_width: the width for which the height should be computed, or -1
|
||||||
|
* @min_height_p: (out) (allow-none): return location for the minimum height
|
||||||
|
* of the layout, or %NULL
|
||||||
|
* @nat_height_p: (out) (allow-none): return location for the natural height
|
||||||
|
* of the layout, or %NULL
|
||||||
|
*
|
||||||
|
* Computes the minimum and natural heights of the @container according
|
||||||
|
* to @manager.
|
||||||
|
*
|
||||||
|
* See also clutter_actor_get_preferred_height()
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_width,
|
||||||
|
gfloat *min_height_p,
|
||||||
|
gfloat *nat_height_p)
|
||||||
|
{
|
||||||
|
ClutterLayoutManagerClass *klass;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
|
||||||
|
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
|
||||||
|
klass->get_preferred_height (manager, container, for_width,
|
||||||
|
min_height_p,
|
||||||
|
nat_height_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_allocate:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: the #ClutterContainer using @manager
|
||||||
|
* @allocation: the #ClutterActorBox containing the allocated area
|
||||||
|
* of @container
|
||||||
|
* @flags: the allocation flags
|
||||||
|
*
|
||||||
|
* Allocates the children of @container given an area
|
||||||
|
*
|
||||||
|
* See also clutter_actor_allocate()
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_allocate (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
const ClutterActorBox *allocation,
|
||||||
|
ClutterAllocationFlags flags)
|
||||||
|
{
|
||||||
|
ClutterLayoutManagerClass *klass;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (allocation != NULL);
|
||||||
|
|
||||||
|
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
|
||||||
|
klass->allocate (manager, container, allocation, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_layout_changed:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
*
|
||||||
|
* Emits the #ClutterLayoutManager::layout-changed signal on @manager
|
||||||
|
*
|
||||||
|
* This function should only be called by implementations of the
|
||||||
|
* #ClutterLayoutManager class
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_layout_changed (ClutterLayoutManager *manager)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
|
||||||
|
g_signal_emit (manager, manager_signals[LAYOUT_CHANGED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_set_container:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: (allow-none): a #ClutterContainer using @manager
|
||||||
|
*
|
||||||
|
* If the #ClutterLayoutManager sub-class allows it, allow
|
||||||
|
* adding a weak reference of the @container using @manager
|
||||||
|
* from within the layout manager
|
||||||
|
*
|
||||||
|
* The layout manager should not increase the reference
|
||||||
|
* count of the @container
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_set_container (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container)
|
||||||
|
{
|
||||||
|
ClutterLayoutManagerClass *klass;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
g_return_if_fail (container == NULL || CLUTTER_IS_CONTAINER (container));
|
||||||
|
|
||||||
|
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
|
||||||
|
if (klass->set_container)
|
||||||
|
klass->set_container (manager, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ClutterLayoutMeta *
|
||||||
|
create_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterLayoutManagerClass *klass;
|
||||||
|
|
||||||
|
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
|
||||||
|
|
||||||
|
return klass->create_child_meta (manager, container, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ClutterLayoutMeta *
|
||||||
|
get_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterLayoutMeta *layout = NULL;
|
||||||
|
|
||||||
|
layout = g_object_get_qdata (G_OBJECT (actor), quark_layout_meta);
|
||||||
|
if (layout != NULL)
|
||||||
|
{
|
||||||
|
ClutterChildMeta *child = CLUTTER_CHILD_META (layout);
|
||||||
|
|
||||||
|
if (layout->manager == manager &&
|
||||||
|
child->container == container &&
|
||||||
|
child->actor == actor)
|
||||||
|
return layout;
|
||||||
|
|
||||||
|
/* if the LayoutMeta referenced is not attached to the
|
||||||
|
* layout manager then we simply ask the layout manager
|
||||||
|
* to replace it with the right one
|
||||||
|
*/
|
||||||
|
layout = create_child_meta (manager, container, actor);
|
||||||
|
if (layout != NULL)
|
||||||
|
{
|
||||||
|
g_assert (CLUTTER_IS_LAYOUT_META (layout));
|
||||||
|
g_object_set_qdata_full (G_OBJECT (actor), quark_layout_meta,
|
||||||
|
layout,
|
||||||
|
(GDestroyNotify) g_object_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_get_child_meta:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: a #ClutterContainer using @manager
|
||||||
|
* @actor: a #ClutterActor child of @container
|
||||||
|
*
|
||||||
|
* Retrieves the #ClutterLayoutMeta that the layout @manager associated
|
||||||
|
* to the @actor child of @container
|
||||||
|
*
|
||||||
|
* Return value: a #ClutterLayoutMeta or %NULL
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
ClutterLayoutMeta *
|
||||||
|
clutter_layout_manager_get_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), NULL);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL);
|
||||||
|
|
||||||
|
return get_child_meta (manager, container, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_add_child_meta:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: a #ClutterContainer using @manager
|
||||||
|
* @actor: a #ClutterActor child of @container
|
||||||
|
*
|
||||||
|
* Creates and binds a #ClutterLayoutMeta for @manager to
|
||||||
|
* a child of @container
|
||||||
|
*
|
||||||
|
* This function should only be used when implementing containers
|
||||||
|
* using #ClutterLayoutManager and not by application code
|
||||||
|
*
|
||||||
|
* Typically, containers should bind a #ClutterLayoutMeta created
|
||||||
|
* by a #ClutterLayoutManager when adding a new child, e.g.:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* static void
|
||||||
|
* my_container_add (ClutterContainer *container,
|
||||||
|
* ClutterActor *actor)
|
||||||
|
* {
|
||||||
|
* MyContainer *self = MY_CONTAINER (container);
|
||||||
|
*
|
||||||
|
* self->children = g_slist_append (self->children, actor);
|
||||||
|
* clutter_actor_set_parent (actor, CLUTTER_ACTOR (self));
|
||||||
|
*
|
||||||
|
* clutter_layout_manager_add_child_meta (self->layout,
|
||||||
|
* container,
|
||||||
|
* actor);
|
||||||
|
*
|
||||||
|
* clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||||
|
*
|
||||||
|
* g_signal_emit_by_name (container, "actor-added");
|
||||||
|
* }
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* The #ClutterLayoutMeta should be removed when removing an
|
||||||
|
* actor; see clutter_layout_manager_remove_child_meta()
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_add_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
|
||||||
|
meta = create_child_meta (manager, container, actor);
|
||||||
|
if (meta == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_object_set_qdata_full (G_OBJECT (actor), quark_layout_meta,
|
||||||
|
meta,
|
||||||
|
(GDestroyNotify) g_object_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_remove_child_meta:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: a #ClutterContainer using @manager
|
||||||
|
* @actor: a #ClutterActor child of @container
|
||||||
|
*
|
||||||
|
* Unbinds and unrefs a #ClutterLayoutMeta for @manager from
|
||||||
|
* a child of @container
|
||||||
|
*
|
||||||
|
* This function should only be used when implementing containers
|
||||||
|
* using #ClutterLayoutManager and not by application code
|
||||||
|
*
|
||||||
|
* Typically, containers should remove a #ClutterLayoutMeta created
|
||||||
|
* by a #ClutterLayoutManager when removing a child, e.g.:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* static void
|
||||||
|
* my_container_remove (ClutterContainer *container,
|
||||||
|
* ClutterActor *actor)
|
||||||
|
* {
|
||||||
|
* MyContainer *self = MY_CONTAINER (container);
|
||||||
|
*
|
||||||
|
* g_object_ref (actor);
|
||||||
|
*
|
||||||
|
* self->children = g_slist_remove (self->children, actor);
|
||||||
|
* clutter_actor_unparent (actor);
|
||||||
|
*
|
||||||
|
* clutter_layout_manager_remove_child_meta (self->layout,
|
||||||
|
* container,
|
||||||
|
* actor);
|
||||||
|
*
|
||||||
|
* clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||||
|
*
|
||||||
|
* g_signal_emit_by_name (container, "actor-removed");
|
||||||
|
*
|
||||||
|
* g_object_unref (actor);
|
||||||
|
* }
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* See also clutter_layout_manager_add_child_meta()
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_remove_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
|
||||||
|
if (get_child_meta (manager, container, actor))
|
||||||
|
g_object_set_qdata (G_OBJECT (actor), quark_layout_meta, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
layout_set_property_internal (ClutterLayoutManager *manager,
|
||||||
|
GObject *gobject,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
const GValue *value)
|
||||||
|
{
|
||||||
|
if (pspec->flags & G_PARAM_CONSTRUCT_ONLY)
|
||||||
|
{
|
||||||
|
g_warning ("%s: Child property '%s' of the layout manager of "
|
||||||
|
"type '%s' is constructor-only",
|
||||||
|
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (manager));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||||
|
{
|
||||||
|
g_warning ("%s: Child property '%s' of the layout manager of "
|
||||||
|
"type '%s' is not writable",
|
||||||
|
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (manager));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set_property (gobject, pspec->name, value);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
layout_get_property_internal (ClutterLayoutManager *manager,
|
||||||
|
GObject *gobject,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
GValue *value)
|
||||||
|
{
|
||||||
|
if (!(pspec->flags & G_PARAM_READABLE))
|
||||||
|
{
|
||||||
|
g_warning ("%s: Child property '%s' of the layout manager of "
|
||||||
|
"type '%s' is not readable",
|
||||||
|
G_STRLOC, pspec->name, G_OBJECT_TYPE_NAME (manager));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_get_property (gobject, pspec->name, value);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_child_set:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: a #ClutterContainer using @manager
|
||||||
|
* @actor: a #ClutterActor child of @container
|
||||||
|
* @first_property: the first property name
|
||||||
|
* @Varargs: a list of property name and value pairs
|
||||||
|
*
|
||||||
|
* Sets a list of properties and their values on the #ClutterLayoutMeta
|
||||||
|
* associated by @manager to a child of @container
|
||||||
|
*
|
||||||
|
* Languages bindings should use clutter_layout_manager_child_set_property()
|
||||||
|
* instead
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_child_set (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_property,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
GObjectClass *klass;
|
||||||
|
const gchar *pname;
|
||||||
|
va_list var_args;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
g_return_if_fail (first_property != NULL);
|
||||||
|
|
||||||
|
meta = get_child_meta (manager, container, actor);
|
||||||
|
if (meta == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Layout managers of type '%s' do not support "
|
||||||
|
"child metadata",
|
||||||
|
g_type_name (G_OBJECT_TYPE (manager)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (meta);
|
||||||
|
|
||||||
|
va_start (var_args, first_property);
|
||||||
|
|
||||||
|
pname = first_property;
|
||||||
|
while (pname)
|
||||||
|
{
|
||||||
|
GValue value = { 0, };
|
||||||
|
GParamSpec *pspec;
|
||||||
|
gchar *error;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
pspec = g_object_class_find_property (klass, pname);
|
||||||
|
if (pspec == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("%s: Layout managers of type '%s' have no child "
|
||||||
|
"property named '%s'",
|
||||||
|
G_STRLOC, G_OBJECT_TYPE_NAME (manager), pname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
G_VALUE_COLLECT (&value, var_args, 0, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error);
|
||||||
|
g_free (error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = layout_set_property_internal (manager, G_OBJECT (meta),
|
||||||
|
pspec,
|
||||||
|
&value);
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pname = va_arg (var_args, gchar*);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end (var_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_child_set_property:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: a #ClutterContainer using @manager
|
||||||
|
* @actor: a #ClutterActor child of @container
|
||||||
|
* @property_name: the name of the property to set
|
||||||
|
* @value: a #GValue with the value of the property to set
|
||||||
|
*
|
||||||
|
* Sets a property on the #ClutterLayoutMeta created by @manager and
|
||||||
|
* attached to a child of @container
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_child_set_property (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *property_name,
|
||||||
|
const GValue *value)
|
||||||
|
{
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
GObjectClass *klass;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
g_return_if_fail (property_name != NULL);
|
||||||
|
g_return_if_fail (value != NULL);
|
||||||
|
|
||||||
|
meta = get_child_meta (manager, container, actor);
|
||||||
|
if (meta == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Layout managers of type '%s' do not support "
|
||||||
|
"child metadata",
|
||||||
|
g_type_name (G_OBJECT_TYPE (manager)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (meta);
|
||||||
|
|
||||||
|
pspec = g_object_class_find_property (klass, property_name);
|
||||||
|
if (pspec == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("%s: Layout managers of type '%s' have no child "
|
||||||
|
"property named '%s'",
|
||||||
|
G_STRLOC, G_OBJECT_TYPE_NAME (manager), property_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout_set_property_internal (manager, G_OBJECT (meta), pspec, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_child_get:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: a #ClutterContainer using @manager
|
||||||
|
* @actor: a #ClutterActor child of @container
|
||||||
|
* @first_property: the name of the first property
|
||||||
|
* @Varargs: a list of property name and return location for the value pairs
|
||||||
|
*
|
||||||
|
* Retrieves the values for a list of properties out of the
|
||||||
|
* #ClutterLayoutMeta created by @manager and attached to the
|
||||||
|
* child of a @container
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_child_get (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_property,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
GObjectClass *klass;
|
||||||
|
const gchar *pname;
|
||||||
|
va_list var_args;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
g_return_if_fail (first_property != NULL);
|
||||||
|
|
||||||
|
meta = get_child_meta (manager, container, actor);
|
||||||
|
if (meta == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Layout managers of type '%s' do not support "
|
||||||
|
"child metadata",
|
||||||
|
g_type_name (G_OBJECT_TYPE (manager)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (meta);
|
||||||
|
|
||||||
|
va_start (var_args, first_property);
|
||||||
|
|
||||||
|
pname = first_property;
|
||||||
|
while (pname)
|
||||||
|
{
|
||||||
|
GValue value = { 0, };
|
||||||
|
GParamSpec *pspec;
|
||||||
|
gchar *error;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
pspec = g_object_class_find_property (klass, pname);
|
||||||
|
if (pspec == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("%s: Layout managers of type '%s' have no child "
|
||||||
|
"property named '%s'",
|
||||||
|
G_STRLOC, G_OBJECT_TYPE_NAME (manager), pname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
|
||||||
|
res = layout_get_property_internal (manager, G_OBJECT (meta),
|
||||||
|
pspec,
|
||||||
|
&value);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
g_value_unset (&value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_VALUE_LCOPY (&value, var_args, 0, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("%s: %s", G_STRLOC, error);
|
||||||
|
g_free (error);
|
||||||
|
g_value_unset (&value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
|
||||||
|
pname = va_arg (var_args, gchar*);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end (var_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_manager_child_get_property:
|
||||||
|
* @manager: a #ClutterLayoutManager
|
||||||
|
* @container: a #ClutterContainer using @manager
|
||||||
|
* @actor: a #ClutterActor child of @container
|
||||||
|
* @property_name: the name of the property to get
|
||||||
|
* @value: a #GValue with the value of the property to get
|
||||||
|
*
|
||||||
|
* Gets a property on the #ClutterLayoutMeta created by @manager and
|
||||||
|
* attached to a child of @container
|
||||||
|
*
|
||||||
|
* The #GValue must already be initialized to the type of the property
|
||||||
|
* and has to be unset with g_value_unset() after extracting the real
|
||||||
|
* value out of it
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_layout_manager_child_get_property (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *property_name,
|
||||||
|
GValue *value)
|
||||||
|
{
|
||||||
|
ClutterLayoutMeta *meta;
|
||||||
|
GObjectClass *klass;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||||
|
g_return_if_fail (property_name != NULL);
|
||||||
|
g_return_if_fail (value != NULL);
|
||||||
|
|
||||||
|
meta = get_child_meta (manager, container, actor);
|
||||||
|
if (meta == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Layout managers of type %s do not support "
|
||||||
|
"child metadata",
|
||||||
|
g_type_name (G_OBJECT_TYPE (manager)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (meta);
|
||||||
|
|
||||||
|
pspec = g_object_class_find_property (klass, property_name);
|
||||||
|
if (pspec == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("%s: Layout managers of type '%s' have no child "
|
||||||
|
"property named '%s'",
|
||||||
|
G_STRLOC, G_OBJECT_TYPE_NAME (manager), property_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout_get_property_internal (manager, G_OBJECT (meta), pspec, value);
|
||||||
|
}
|
187
clutter/clutter-layout-manager.h
Normal file
187
clutter/clutter-layout-manager.h
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* 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_LAYOUT_MANAGER_H__
|
||||||
|
#define __CLUTTER_LAYOUT_MANAGER_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-actor.h>
|
||||||
|
#include <clutter/clutter-container.h>
|
||||||
|
#include <clutter/clutter-types.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_LAYOUT_MANAGER (clutter_layout_manager_get_type ())
|
||||||
|
#define CLUTTER_LAYOUT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYOUT_MANAGER, ClutterLayoutManager))
|
||||||
|
#define CLUTTER_IS_LAYOUT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LAYOUT_MANAGER))
|
||||||
|
#define CLUTTER_LAYOUT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_LAYOUT_MANAGER, ClutterLayoutManagerClass))
|
||||||
|
#define CLUTTER_IS_LAYOUT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_LAYOUT_MANAGER))
|
||||||
|
#define CLUTTER_LAYOUT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_LAYOUT_MANAGER, ClutterLayoutManagerClass))
|
||||||
|
|
||||||
|
typedef struct _ClutterLayoutManager ClutterLayoutManager;
|
||||||
|
typedef struct _ClutterLayoutManagerClass ClutterLayoutManagerClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterLayoutManager:
|
||||||
|
*
|
||||||
|
* The #ClutterLayoutManager structure contains only private data
|
||||||
|
* and should be accessed using the provided API
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _ClutterLayoutManager
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GInitiallyUnowned parent_instance;
|
||||||
|
|
||||||
|
/* padding for future expansion */
|
||||||
|
gpointer dummy;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterLayoutManagerClass:
|
||||||
|
* @get_preferred_width: virtual function; override to provide a preferred
|
||||||
|
* width for the layout manager. See also the get_preferred_width()
|
||||||
|
* virtual function in #ClutterActor
|
||||||
|
* @get_preferred_height: virtual function; override to provide a preferred
|
||||||
|
* height for the layout manager. See also the get_preferred_height()
|
||||||
|
* virtual function in #ClutterActor
|
||||||
|
* @allocate: virtual function; override to allocate the children of the
|
||||||
|
* layout manager. See also the allocate() virtual function in
|
||||||
|
* #ClutterActor
|
||||||
|
* @set_container: virtual function; override to set a back pointer
|
||||||
|
* on the #ClutterContainer using the layout manager. The implementation
|
||||||
|
* should not take a reference on the container, but just take a weak
|
||||||
|
* reference, to avoid potential leaks due to reference cycles
|
||||||
|
* @create_child_meta: virtual function; override to create a
|
||||||
|
* #ClutterChildMeta instance associated to a #ClutterContainer and a
|
||||||
|
* child #ClutterActor, used to maintain layout manager specific properties
|
||||||
|
* @layout_changed: class handler for the #ClutterLayoutManager::layout-changed
|
||||||
|
* signal
|
||||||
|
*
|
||||||
|
* The #ClutterLayoutManagerClass structure contains only private
|
||||||
|
* data and should be accessed using the provided API
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _ClutterLayoutManagerClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GInitiallyUnownedClass parent_class;
|
||||||
|
|
||||||
|
/*< public >*/
|
||||||
|
void (* get_preferred_width) (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_height,
|
||||||
|
gfloat *minimum_width_p,
|
||||||
|
gfloat *natural_width_p);
|
||||||
|
void (* get_preferred_height) (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_width,
|
||||||
|
gfloat *minimum_height_p,
|
||||||
|
gfloat *natural_height_p);
|
||||||
|
void (* allocate) (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
const ClutterActorBox *allocation,
|
||||||
|
ClutterAllocationFlags flags);
|
||||||
|
|
||||||
|
void (* set_container) (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container);
|
||||||
|
|
||||||
|
ClutterLayoutMeta *(* create_child_meta) (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
void (* layout_changed) (ClutterLayoutManager *manager);
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
/* padding for future expansion */
|
||||||
|
void (* _clutter_padding_1) (void);
|
||||||
|
void (* _clutter_padding_2) (void);
|
||||||
|
void (* _clutter_padding_3) (void);
|
||||||
|
void (* _clutter_padding_4) (void);
|
||||||
|
void (* _clutter_padding_5) (void);
|
||||||
|
void (* _clutter_padding_6) (void);
|
||||||
|
void (* _clutter_padding_7) (void);
|
||||||
|
void (* _clutter_padding_8) (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_layout_manager_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
void clutter_layout_manager_get_preferred_width (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_height,
|
||||||
|
gfloat *min_width_p,
|
||||||
|
gfloat *nat_width_p);
|
||||||
|
void clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
gfloat for_width,
|
||||||
|
gfloat *min_height_p,
|
||||||
|
gfloat *nat_height_p);
|
||||||
|
void clutter_layout_manager_allocate (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
const ClutterActorBox *allocation,
|
||||||
|
ClutterAllocationFlags flags);
|
||||||
|
|
||||||
|
void clutter_layout_manager_set_container (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container);
|
||||||
|
void clutter_layout_manager_layout_changed (ClutterLayoutManager *manager);
|
||||||
|
|
||||||
|
ClutterLayoutMeta *clutter_layout_manager_get_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
void clutter_layout_manager_add_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
void clutter_layout_manager_remove_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor);
|
||||||
|
|
||||||
|
void clutter_layout_manager_child_set (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_property,
|
||||||
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
void clutter_layout_manager_child_get (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *first_property,
|
||||||
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
void clutter_layout_manager_child_set_property (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *property_name,
|
||||||
|
const GValue *value);
|
||||||
|
void clutter_layout_manager_child_get_property (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor,
|
||||||
|
const gchar *property_name,
|
||||||
|
GValue *value);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_LAYOUT_MANAGER_H__ */
|
142
clutter/clutter-layout-meta.c
Normal file
142
clutter/clutter-layout-meta.c
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* 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-layout-meta
|
||||||
|
* @short_description: Wrapper for actors inside a layout manager
|
||||||
|
*
|
||||||
|
* #ClutterLayoutMeta is a wrapper object created by #ClutterLayoutManager
|
||||||
|
* implementations in order to store child-specific data and properties.
|
||||||
|
*
|
||||||
|
* A #ClutterLayoutMeta wraps a #ClutterActor inside a #ClutterContainer
|
||||||
|
* using a #ClutterLayoutManager.
|
||||||
|
*
|
||||||
|
* #ClutterLayoutMeta is available since Clutter 1.2
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "clutter-layout-meta.h"
|
||||||
|
#include "clutter-debug.h"
|
||||||
|
#include "clutter-private.h"
|
||||||
|
|
||||||
|
G_DEFINE_ABSTRACT_TYPE (ClutterLayoutMeta,
|
||||||
|
clutter_layout_meta,
|
||||||
|
CLUTTER_TYPE_CHILD_META);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_MANAGER
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_layout_meta_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterLayoutMeta *layout_meta = CLUTTER_LAYOUT_META (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_MANAGER:
|
||||||
|
layout_meta->manager = g_value_get_object (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_layout_meta_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClutterLayoutMeta *layout_meta = CLUTTER_LAYOUT_META (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_MANAGER:
|
||||||
|
g_value_set_object (value, layout_meta->manager);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_layout_meta_class_init (ClutterLayoutMetaClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
gobject_class->set_property = clutter_layout_meta_set_property;
|
||||||
|
gobject_class->get_property = clutter_layout_meta_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterLayoutMeta:manager:
|
||||||
|
*
|
||||||
|
* The #ClutterLayoutManager that created this #ClutterLayoutMeta.
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_object ("manager",
|
||||||
|
"Manager",
|
||||||
|
"The manager that created this data",
|
||||||
|
CLUTTER_TYPE_LAYOUT_MANAGER,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_MANAGER, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_layout_meta_init (ClutterLayoutMeta *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_layout_meta_get_manager:
|
||||||
|
* @data: a #ClutterLayoutMeta
|
||||||
|
*
|
||||||
|
* Retrieves the actor wrapped by @data
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): a #ClutterLayoutManager
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
ClutterLayoutManager *
|
||||||
|
clutter_layout_meta_get_manager (ClutterLayoutMeta *data)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_LAYOUT_META (data), NULL);
|
||||||
|
|
||||||
|
return data->manager;
|
||||||
|
}
|
85
clutter/clutter-layout-meta.h
Normal file
85
clutter/clutter-layout-meta.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* 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_LAYOUT_META_H__
|
||||||
|
#define __CLUTTER_LAYOUT_META_H__
|
||||||
|
|
||||||
|
#include <clutter/clutter-types.h>
|
||||||
|
#include <clutter/clutter-child-meta.h>
|
||||||
|
#include <clutter/clutter-layout-manager.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLUTTER_TYPE_LAYOUT_META (clutter_layout_meta_get_type ())
|
||||||
|
#define CLUTTER_LAYOUT_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYOUT_META, ClutterLayoutMeta))
|
||||||
|
#define CLUTTER_IS_LAYOUT_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LAYOUT_META))
|
||||||
|
#define CLUTTER_LAYOUT_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_LAYOUT_META, ClutterLayoutMetaClass))
|
||||||
|
#define CLUTTER_IS_LAYOUT_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_LAYOUT_META))
|
||||||
|
#define CLUTTER_LAYOUT_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_LAYOUT_META, ClutterLayoutMetaClass))
|
||||||
|
|
||||||
|
/* ClutterLayoutMeta is defined in clutter-types.h */
|
||||||
|
|
||||||
|
typedef struct _ClutterLayoutMetaClass ClutterLayoutMetaClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterLayoutMeta
|
||||||
|
* @manager: the layout manager handling this data
|
||||||
|
*
|
||||||
|
* Sub-class of #ClutterChildMeta specific for layout managers
|
||||||
|
*
|
||||||
|
* A #ClutterLayoutManager sub-class should create a #ClutterLayoutMeta
|
||||||
|
* instance by overriding the #ClutterLayoutManager::create_child_meta()
|
||||||
|
* virtual function
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
*/
|
||||||
|
struct _ClutterLayoutMeta
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
ClutterChildMeta parent_instance;
|
||||||
|
|
||||||
|
/*< public >*/
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
/* padding */
|
||||||
|
gpointer dummy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ClutterLayoutMetaClass
|
||||||
|
{
|
||||||
|
ClutterChildMetaClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType clutter_layout_meta_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
ClutterLayoutManager *clutter_layout_meta_get_manager (ClutterLayoutMeta *data);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __CLUTTER_LAYOUT_META_H__ */
|
@ -43,6 +43,7 @@ typedef struct _ClutterActor ClutterActor;
|
|||||||
typedef struct _ClutterStage ClutterStage;
|
typedef struct _ClutterStage ClutterStage;
|
||||||
typedef struct _ClutterContainer ClutterContainer; /* dummy */
|
typedef struct _ClutterContainer ClutterContainer; /* dummy */
|
||||||
typedef struct _ClutterChildMeta ClutterChildMeta;
|
typedef struct _ClutterChildMeta ClutterChildMeta;
|
||||||
|
typedef struct _ClutterLayoutMeta ClutterLayoutMeta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterGravity:
|
* ClutterGravity:
|
||||||
|
@ -43,6 +43,9 @@
|
|||||||
#include "clutter-behaviour-rotate.h"
|
#include "clutter-behaviour-rotate.h"
|
||||||
#include "clutter-behaviour-scale.h"
|
#include "clutter-behaviour-scale.h"
|
||||||
#include "clutter-binding-pool.h"
|
#include "clutter-binding-pool.h"
|
||||||
|
#include "clutter-bin-layout.h"
|
||||||
|
#include "clutter-box.h"
|
||||||
|
#include "clutter-box-layout.h"
|
||||||
#include "clutter-cairo-texture.h"
|
#include "clutter-cairo-texture.h"
|
||||||
#include "clutter-child-meta.h"
|
#include "clutter-child-meta.h"
|
||||||
#include "clutter-clone.h"
|
#include "clutter-clone.h"
|
||||||
@ -50,10 +53,14 @@
|
|||||||
#include "clutter-container.h"
|
#include "clutter-container.h"
|
||||||
#include "clutter-event.h"
|
#include "clutter-event.h"
|
||||||
#include "clutter-feature.h"
|
#include "clutter-feature.h"
|
||||||
|
#include "clutter-fixed-layout.h"
|
||||||
|
#include "clutter-flow-layout.h"
|
||||||
#include "clutter-frame-source.h"
|
#include "clutter-frame-source.h"
|
||||||
#include "clutter-group.h"
|
#include "clutter-group.h"
|
||||||
#include "clutter-interval.h"
|
#include "clutter-interval.h"
|
||||||
#include "clutter-keysyms.h"
|
#include "clutter-keysyms.h"
|
||||||
|
#include "clutter-layout-manager.h"
|
||||||
|
#include "clutter-layout-meta.h"
|
||||||
#include "clutter-list-model.h"
|
#include "clutter-list-model.h"
|
||||||
#include "clutter-main.h"
|
#include "clutter-main.h"
|
||||||
#include "clutter-media.h"
|
#include "clutter-media.h"
|
||||||
|
@ -55,6 +55,8 @@
|
|||||||
<xi:include href="xml/clutter-container.xml"/>
|
<xi:include href="xml/clutter-container.xml"/>
|
||||||
<xi:include href="xml/clutter-child-meta.xml"/>
|
<xi:include href="xml/clutter-child-meta.xml"/>
|
||||||
<xi:include href="xml/clutter-media.xml"/>
|
<xi:include href="xml/clutter-media.xml"/>
|
||||||
|
<xi:include href="xml/clutter-layout-manager.xml"/>
|
||||||
|
<xi:include href="xml/clutter-layout-meta.xml"/>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter>
|
<chapter>
|
||||||
@ -71,6 +73,16 @@
|
|||||||
|
|
||||||
<xi:include href="xml/clutter-group.xml"/>
|
<xi:include href="xml/clutter-group.xml"/>
|
||||||
<xi:include href="xml/clutter-stage.xml"/>
|
<xi:include href="xml/clutter-stage.xml"/>
|
||||||
|
<xi:include href="xml/clutter-box.xml"/>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<chapter>
|
||||||
|
<title>Layout managers</title>
|
||||||
|
|
||||||
|
<xi:include href="xml/clutter-fixed-layout.xml"/>
|
||||||
|
<xi:include href="xml/clutter-bin-layout.xml"/>
|
||||||
|
<xi:include href="xml/clutter-flow-layout.xml"/>
|
||||||
|
<xi:include href="xml/clutter-box-layout.xml"/>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
</part>
|
</part>
|
||||||
@ -198,13 +210,13 @@
|
|||||||
<chapter id="clutterobjecthierarchy">
|
<chapter id="clutterobjecthierarchy">
|
||||||
<title>Object Hierarchy</title>
|
<title>Object Hierarchy</title>
|
||||||
|
|
||||||
<xi:include href="xml/tree_index.sgml"/>
|
<xi:include href="xml/tree_index.sgml"><xi:fallback /></xi:include>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
<chapter id="clutterobjectindex">
|
<chapter id="clutterobjectindex">
|
||||||
<title>Object Index</title>
|
<title>Object Index</title>
|
||||||
|
|
||||||
<xi:include href="xml/object_index.sgml"/>
|
<xi:include href="xml/object_index.sgml"><xi:fallback /></xi:include>
|
||||||
</chapter>
|
</chapter>
|
||||||
</part>
|
</part>
|
||||||
|
|
||||||
|
@ -305,6 +305,8 @@ clutter_actor_get_preferred_width
|
|||||||
clutter_actor_get_preferred_height
|
clutter_actor_get_preferred_height
|
||||||
clutter_actor_set_fixed_position_set
|
clutter_actor_set_fixed_position_set
|
||||||
clutter_actor_get_fixed_position_set
|
clutter_actor_get_fixed_position_set
|
||||||
|
clutter_actor_set_request_mode
|
||||||
|
clutter_actor_get_request_mode
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
clutter_actor_set_geometry
|
clutter_actor_set_geometry
|
||||||
@ -1726,3 +1728,195 @@ CLUTTER_STAGE_MANAGER_GET_CLASS
|
|||||||
<SUBSECTION Private>
|
<SUBSECTION Private>
|
||||||
clutter_stage_manager_get_type
|
clutter_stage_manager_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<TITLE>Layout Managers</TITLE>
|
||||||
|
<FILE>clutter-layout-manager</FILE>
|
||||||
|
ClutterLayoutManager
|
||||||
|
ClutterLayoutManagerClass
|
||||||
|
clutter_layout_manager_get_preferred_width
|
||||||
|
clutter_layout_manager_get_preferred_height
|
||||||
|
clutter_layout_manager_allocate
|
||||||
|
clutter_layout_manager_layout_changed
|
||||||
|
clutter_layout_manager_set_container
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_layout_manager_add_child_meta
|
||||||
|
clutter_layout_manager_remove_child_meta
|
||||||
|
clutter_layout_manager_get_child_meta
|
||||||
|
clutter_layout_manager_child_set
|
||||||
|
clutter_layout_manager_child_set_property
|
||||||
|
clutter_layout_manager_child_get
|
||||||
|
clutter_layout_manager_child_get_property
|
||||||
|
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_TYPE_LAYOUT_MANAGER
|
||||||
|
CLUTTER_LAYOUT_MANAGER
|
||||||
|
CLUTTER_LAYOUT_MANAGER_CLASS
|
||||||
|
CLUTTER_IS_LAYOUT_MANAGER
|
||||||
|
CLUTTER_IS_LAYOUT_MANAGER_CLASS
|
||||||
|
CLUTTER_LAYOUT_MANAGER_GET_CLASS
|
||||||
|
|
||||||
|
<SUBSECTION Private>
|
||||||
|
clutter_layout_manager_get_type
|
||||||
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<TITLE>ClutterFixedLayout</TITLE>
|
||||||
|
<FILE>clutter-fixed-layout</FILE>
|
||||||
|
ClutterFixedLayout
|
||||||
|
ClutterFixedLayoutClass
|
||||||
|
clutter_fixed_layout_new
|
||||||
|
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_TYPE_FIXED_LAYOUT
|
||||||
|
CLUTTER_FIXED_LAYOUT
|
||||||
|
CLUTTER_FIXED_LAYOUT_CLASS
|
||||||
|
CLUTTER_IS_FIXED_LAYOUT
|
||||||
|
CLUTTER_IS_FIXED_LAYOUT_CLASS
|
||||||
|
CLUTTER_FIXED_LAYOUT_GET_CLASS
|
||||||
|
|
||||||
|
<SUBSECTION Private>
|
||||||
|
clutter_fixed_layout_get_type
|
||||||
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<TITLE>ClutterBinLayout</TITLE>
|
||||||
|
<FILE>clutter-bin-layout</FILE>
|
||||||
|
ClutterBinAlignment
|
||||||
|
ClutterBinLayout
|
||||||
|
ClutterBinLayoutClass
|
||||||
|
clutter_bin_layout_new
|
||||||
|
clutter_bin_layout_set_alignment
|
||||||
|
clutter_bin_layout_get_alignment
|
||||||
|
clutter_bin_layout_add
|
||||||
|
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_TYPE_BIN_LAYOUT
|
||||||
|
CLUTTER_BIN_LAYOUT
|
||||||
|
CLUTTER_BIN_LAYOUT_CLASS
|
||||||
|
CLUTTER_IS_BIN_LAYOUT
|
||||||
|
CLUTTER_IS_BIN_LAYOUT_CLASS
|
||||||
|
CLUTTER_BIN_LAYOUT_GET_CLASS
|
||||||
|
|
||||||
|
<SUBSECTION Private>
|
||||||
|
ClutterBinLayoutPrivate
|
||||||
|
clutter_bin_layout_get_type
|
||||||
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<TITLE>ClutterBox</TITLE>
|
||||||
|
<FILE>clutter-box</FILE>
|
||||||
|
ClutterBox
|
||||||
|
ClutterBoxClass
|
||||||
|
clutter_box_new
|
||||||
|
clutter_box_set_layout_manager
|
||||||
|
clutter_box_get_layout_manager
|
||||||
|
clutter_box_set_color
|
||||||
|
clutter_box_get_color
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_box_pack
|
||||||
|
clutter_box_packv
|
||||||
|
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_TYPE_BOX
|
||||||
|
CLUTTER_BOX
|
||||||
|
CLUTTER_BOX_CLASS
|
||||||
|
CLUTTER_IS_BOX
|
||||||
|
CLUTTER_IS_BOX_CLASS
|
||||||
|
CLUTTER_BOX_GET_CLASS
|
||||||
|
|
||||||
|
<SUBSECTION Private>
|
||||||
|
ClutterBoxPrivate
|
||||||
|
clutter_box_get_type
|
||||||
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<TITLE>ClutterLayoutMeta</TITLE>
|
||||||
|
<FILE>clutter-layout-meta</FILE>
|
||||||
|
ClutterLayoutMeta
|
||||||
|
ClutterLayoutMetaClass
|
||||||
|
clutter_layout_meta_get_manager
|
||||||
|
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_TYPE_LAYOUT_META
|
||||||
|
CLUTTER_LAYOUT_META
|
||||||
|
CLUTTER_LAYOUT_META_CLASS
|
||||||
|
CLUTTER_IS_LAYOUT_META
|
||||||
|
CLUTTER_IS_LAYOUT_META_CLASS
|
||||||
|
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
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<TITLE>ClutterBoxLayout</TITLE>
|
||||||
|
<FILE>clutter-box-layout</FILE>
|
||||||
|
ClutterBoxAlignment
|
||||||
|
ClutterBoxLayout
|
||||||
|
ClutterBoxLayoutClass
|
||||||
|
clutter_box_layout_new
|
||||||
|
clutter_box_layout_set_pack_start
|
||||||
|
clutter_box_layout_get_pack_start
|
||||||
|
clutter_box_layout_set_spacing
|
||||||
|
clutter_box_layout_get_spacing
|
||||||
|
clutter_box_layout_set_vertical
|
||||||
|
clutter_box_layout_get_vertical
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_box_layout_pack
|
||||||
|
|
||||||
|
<SUBSECTION>
|
||||||
|
clutter_box_layout_set_alignment
|
||||||
|
clutter_box_layout_get_alignment
|
||||||
|
clutter_box_layout_set_expand
|
||||||
|
clutter_box_layout_get_expand
|
||||||
|
clutter_box_layout_set_fill
|
||||||
|
clutter_box_layout_get_fill
|
||||||
|
|
||||||
|
<SUBSECTION Standard>
|
||||||
|
CLUTTER_TYPE_BOX_LAYOUT
|
||||||
|
CLUTTER_BOX_LAYOUT
|
||||||
|
CLUTTER_BOX_LAYOUT_CLASS
|
||||||
|
CLUTTER_IS_BOX_LAYOUT
|
||||||
|
CLUTTER_IS_BOX_LAYOUT_CLASS
|
||||||
|
CLUTTER_BOX_LAYOUT_GET_CLASS
|
||||||
|
|
||||||
|
<SUBSECTION Private>
|
||||||
|
ClutterBoxLayoutPrivate
|
||||||
|
clutter_box_layout_get_type
|
||||||
|
</SECTION>
|
||||||
|
@ -33,3 +33,10 @@ clutter_animation_get_type
|
|||||||
clutter_interval_get_type
|
clutter_interval_get_type
|
||||||
clutter_stage_manager_get_type
|
clutter_stage_manager_get_type
|
||||||
clutter_binding_pool_get_type
|
clutter_binding_pool_get_type
|
||||||
|
clutter_box_get_type
|
||||||
|
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
|
||||||
|
clutter_box_layout_get_type
|
||||||
|
@ -43,7 +43,10 @@ UNIT_TESTS = \
|
|||||||
test-text.c \
|
test-text.c \
|
||||||
test-text-field.c \
|
test-text-field.c \
|
||||||
test-clutter-cairo-flowers.c \
|
test-clutter-cairo-flowers.c \
|
||||||
test-cogl-vertex-buffer.c
|
test-cogl-vertex-buffer.c \
|
||||||
|
test-bin-layout.c \
|
||||||
|
test-flow-layout.c \
|
||||||
|
test-box-layout.c
|
||||||
|
|
||||||
if X11_TESTS
|
if X11_TESTS
|
||||||
UNIT_TESTS += test-pixmap.c
|
UNIT_TESTS += test-pixmap.c
|
||||||
|
185
tests/interactive/test-bin-layout.c
Normal file
185
tests/interactive/test-bin-layout.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <cairo/cairo.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
static ClutterActor *
|
||||||
|
make_background (const ClutterColor *color,
|
||||||
|
gfloat width,
|
||||||
|
gfloat height)
|
||||||
|
{
|
||||||
|
ClutterActor *tex = clutter_cairo_texture_new (width, height);
|
||||||
|
cairo_t *cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (tex));
|
||||||
|
cairo_pattern_t *pat;
|
||||||
|
gfloat x, y;
|
||||||
|
|
||||||
|
#define BG_ROUND_RADIUS 12
|
||||||
|
|
||||||
|
x = y = 0;
|
||||||
|
|
||||||
|
cairo_move_to (cr, BG_ROUND_RADIUS, y);
|
||||||
|
cairo_line_to (cr, width - BG_ROUND_RADIUS, y);
|
||||||
|
cairo_curve_to (cr, width, y, width, y, width, BG_ROUND_RADIUS);
|
||||||
|
cairo_line_to (cr, width, height - BG_ROUND_RADIUS);
|
||||||
|
cairo_curve_to (cr, width, height, width, height, width - BG_ROUND_RADIUS, height);
|
||||||
|
cairo_line_to (cr, BG_ROUND_RADIUS, height);
|
||||||
|
cairo_curve_to (cr, x, height, x, height, x, height - BG_ROUND_RADIUS);
|
||||||
|
cairo_line_to (cr, x, BG_ROUND_RADIUS);
|
||||||
|
cairo_curve_to (cr, x, y, x, y, BG_ROUND_RADIUS, y);
|
||||||
|
|
||||||
|
cairo_close_path (cr);
|
||||||
|
|
||||||
|
clutter_cairo_set_source_color (cr, color);
|
||||||
|
cairo_stroke (cr);
|
||||||
|
|
||||||
|
x += 4;
|
||||||
|
y += 4;
|
||||||
|
width -= 4;
|
||||||
|
height -= 4;
|
||||||
|
|
||||||
|
cairo_move_to (cr, BG_ROUND_RADIUS, y);
|
||||||
|
cairo_line_to (cr, width - BG_ROUND_RADIUS, y);
|
||||||
|
cairo_curve_to (cr, width, y, width, y, width, BG_ROUND_RADIUS);
|
||||||
|
cairo_line_to (cr, width, height - BG_ROUND_RADIUS);
|
||||||
|
cairo_curve_to (cr, width, height, width, height, width - BG_ROUND_RADIUS, height);
|
||||||
|
cairo_line_to (cr, BG_ROUND_RADIUS, height);
|
||||||
|
cairo_curve_to (cr, x, height, x, height, x, height - BG_ROUND_RADIUS);
|
||||||
|
cairo_line_to (cr, x, BG_ROUND_RADIUS);
|
||||||
|
cairo_curve_to (cr, x, y, x, y, BG_ROUND_RADIUS, y);
|
||||||
|
|
||||||
|
cairo_close_path (cr);
|
||||||
|
|
||||||
|
pat = cairo_pattern_create_linear (0, 0, 0, height);
|
||||||
|
cairo_pattern_add_color_stop_rgba (pat, 1, .85, .85, .85, 1);
|
||||||
|
cairo_pattern_add_color_stop_rgba (pat, .95, 1, 1, 1, 1);
|
||||||
|
cairo_pattern_add_color_stop_rgba (pat, .05, 1, 1, 1, 1);
|
||||||
|
cairo_pattern_add_color_stop_rgba (pat, 0, .85, .85, .85, 1);
|
||||||
|
|
||||||
|
cairo_set_source (cr, pat);
|
||||||
|
cairo_fill (cr);
|
||||||
|
|
||||||
|
cairo_pattern_destroy (pat);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
|
#undef BG_ROUND_RADIUS
|
||||||
|
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_box_enter (ClutterActor *box,
|
||||||
|
ClutterEvent *event,
|
||||||
|
ClutterActor *emblem)
|
||||||
|
{
|
||||||
|
clutter_actor_animate (emblem, CLUTTER_LINEAR, 150,
|
||||||
|
"opacity", 255,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_box_leave (ClutterActor *box,
|
||||||
|
ClutterEvent *event,
|
||||||
|
ClutterActor *emblem)
|
||||||
|
{
|
||||||
|
clutter_actor_animate (emblem, CLUTTER_LINEAR, 150,
|
||||||
|
"opacity", 0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_MODULE_EXPORT int
|
||||||
|
test_bin_layout_main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
ClutterActor *stage, *box, *rect;
|
||||||
|
ClutterLayoutManager *layout;
|
||||||
|
ClutterColor stage_color = { 0xe0, 0xf2, 0xfc, 0xff };
|
||||||
|
ClutterColor bg_color = { 0xcc, 0xcc, 0xcc, 0x99 };
|
||||||
|
ClutterColor *color;
|
||||||
|
|
||||||
|
clutter_init (&argc, &argv);
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
clutter_stage_set_title (CLUTTER_STAGE (stage), "Box test");
|
||||||
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||||
|
clutter_actor_set_size (stage, 640, 480);
|
||||||
|
|
||||||
|
layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER);
|
||||||
|
|
||||||
|
box = clutter_box_new (layout);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
|
||||||
|
clutter_actor_set_anchor_point_from_gravity (box, CLUTTER_GRAVITY_CENTER);
|
||||||
|
clutter_actor_set_position (box, 320, 240);
|
||||||
|
clutter_actor_set_reactive (box, TRUE);
|
||||||
|
clutter_actor_set_name (box, "box");
|
||||||
|
|
||||||
|
rect = make_background (&bg_color, 200, 200);
|
||||||
|
|
||||||
|
/* first method: use clutter_box_pack() */
|
||||||
|
clutter_box_pack (CLUTTER_BOX (box), rect,
|
||||||
|
"x-align", CLUTTER_BIN_ALIGNMENT_FILL,
|
||||||
|
"y-align", CLUTTER_BIN_ALIGNMENT_FILL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
clutter_actor_lower_bottom (rect);
|
||||||
|
clutter_actor_set_name (rect, "background");
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
ClutterActor *tex;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
tex = clutter_texture_new_from_file ("redhand.png", &error);
|
||||||
|
if (error)
|
||||||
|
g_error ("Unable to create texture: %s", error->message);
|
||||||
|
|
||||||
|
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (tex), TRUE);
|
||||||
|
|
||||||
|
/* second method: use clutter_bin_layout_add() */
|
||||||
|
clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (layout), tex,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER);
|
||||||
|
|
||||||
|
clutter_actor_raise (tex, rect);
|
||||||
|
clutter_actor_set_width (tex, 175);
|
||||||
|
clutter_actor_set_name (tex, "texture");
|
||||||
|
}
|
||||||
|
|
||||||
|
color = clutter_color_new (g_random_int_range (0, 255),
|
||||||
|
g_random_int_range (0, 255),
|
||||||
|
g_random_int_range (0, 255),
|
||||||
|
224);
|
||||||
|
|
||||||
|
rect = clutter_rectangle_new_with_color (color);
|
||||||
|
|
||||||
|
/* third method: container_add() and set_alignment() */
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (box), rect);
|
||||||
|
clutter_bin_layout_set_alignment (CLUTTER_BIN_LAYOUT (layout), rect,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_END,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_END);
|
||||||
|
|
||||||
|
clutter_actor_set_size (rect, 50, 50);
|
||||||
|
clutter_actor_set_opacity (rect, 0);
|
||||||
|
clutter_actor_raise_top (rect);
|
||||||
|
clutter_actor_set_name (rect, "emblem");
|
||||||
|
|
||||||
|
|
||||||
|
g_signal_connect (box,
|
||||||
|
"enter-event", G_CALLBACK (on_box_enter),
|
||||||
|
rect);
|
||||||
|
g_signal_connect (box,
|
||||||
|
"leave-event", G_CALLBACK (on_box_leave),
|
||||||
|
rect);
|
||||||
|
|
||||||
|
clutter_actor_show_all (stage);
|
||||||
|
|
||||||
|
clutter_main ();
|
||||||
|
|
||||||
|
clutter_color_free (color);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
207
tests/interactive/test-box-layout.c
Normal file
207
tests/interactive/test-box-layout.c
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <gmodule.h>
|
||||||
|
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
static ClutterActor *hover_actor = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
enter_event (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
ClutterColor color = { 0x00, 0x00, 0x00, 0xff };
|
||||||
|
|
||||||
|
clutter_rectangle_set_border_width (CLUTTER_RECTANGLE (actor), 2);
|
||||||
|
clutter_rectangle_set_border_color (CLUTTER_RECTANGLE (actor), &color);
|
||||||
|
|
||||||
|
hover_actor = actor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
leave_event (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
clutter_rectangle_set_border_width (CLUTTER_RECTANGLE (actor), 0);
|
||||||
|
|
||||||
|
hover_actor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
button_release_event (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
ClutterBoxLayout *box)
|
||||||
|
{
|
||||||
|
gboolean xfill, yfill;
|
||||||
|
ClutterBoxAlignment xalign, yalign;
|
||||||
|
gint button;
|
||||||
|
|
||||||
|
button = clutter_event_get_button (event);
|
||||||
|
|
||||||
|
if (button == 1)
|
||||||
|
{
|
||||||
|
clutter_box_layout_get_fill (box, actor, &xfill, &yfill);
|
||||||
|
clutter_box_layout_set_fill (box, actor,
|
||||||
|
xfill ? FALSE : TRUE,
|
||||||
|
yfill ? FALSE : TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clutter_box_layout_get_alignment (box, actor, &xalign, &yalign);
|
||||||
|
|
||||||
|
if (xalign < 2)
|
||||||
|
xalign += 1;
|
||||||
|
else
|
||||||
|
xalign = 0;
|
||||||
|
|
||||||
|
if (yalign < 2)
|
||||||
|
yalign += 1;
|
||||||
|
else
|
||||||
|
yalign = 0;
|
||||||
|
|
||||||
|
clutter_box_layout_set_alignment (box, actor, xalign, yalign);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_actor (ClutterBoxLayout *box)
|
||||||
|
{
|
||||||
|
ClutterActor *rect;
|
||||||
|
ClutterColor color = { 0xff, 0xff, 0xff, 255 };
|
||||||
|
static gboolean expand = TRUE;
|
||||||
|
|
||||||
|
clutter_color_from_hls (&color,
|
||||||
|
g_random_double_range (0.0, 360.0),
|
||||||
|
0.5,
|
||||||
|
0.5);
|
||||||
|
|
||||||
|
rect = clutter_rectangle_new_with_color (&color);
|
||||||
|
clutter_actor_set_size (rect, 32, 64);
|
||||||
|
clutter_box_layout_pack (box, rect, expand,
|
||||||
|
FALSE, /* x-fill */
|
||||||
|
FALSE, /* y-fill */
|
||||||
|
CLUTTER_BOX_ALIGNMENT_CENTER,
|
||||||
|
CLUTTER_BOX_ALIGNMENT_CENTER);
|
||||||
|
|
||||||
|
clutter_actor_set_reactive (rect, TRUE);
|
||||||
|
g_signal_connect (rect, "enter-event", G_CALLBACK (enter_event), NULL);
|
||||||
|
g_signal_connect (rect, "leave-event", G_CALLBACK (leave_event), NULL);
|
||||||
|
g_signal_connect (rect, "button-release-event",
|
||||||
|
G_CALLBACK (button_release_event),
|
||||||
|
box);
|
||||||
|
|
||||||
|
expand = !expand;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
key_release_cb (ClutterActor *actor,
|
||||||
|
ClutterEvent *event,
|
||||||
|
ClutterBoxLayout *layout)
|
||||||
|
{
|
||||||
|
gboolean toggle;
|
||||||
|
guint spacing;
|
||||||
|
|
||||||
|
switch (clutter_event_get_key_symbol (event))
|
||||||
|
{
|
||||||
|
case CLUTTER_v:
|
||||||
|
toggle = clutter_box_layout_get_vertical (layout);
|
||||||
|
clutter_box_layout_set_vertical (layout, !toggle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_p:
|
||||||
|
toggle = clutter_box_layout_get_pack_start (layout);
|
||||||
|
clutter_box_layout_set_pack_start (layout, !toggle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_s:
|
||||||
|
spacing = clutter_box_layout_get_spacing (layout);
|
||||||
|
|
||||||
|
if (spacing > 12)
|
||||||
|
spacing = 0;
|
||||||
|
else
|
||||||
|
spacing++;
|
||||||
|
|
||||||
|
clutter_box_layout_set_spacing (layout, spacing);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '+':
|
||||||
|
add_actor (layout);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stage_size_changed_cb (ClutterActor *stage,
|
||||||
|
const ClutterActorBox *allocation,
|
||||||
|
ClutterAllocationFlags flags,
|
||||||
|
ClutterActor *box)
|
||||||
|
{
|
||||||
|
gfloat width, height;
|
||||||
|
|
||||||
|
clutter_actor_box_get_size (allocation, &width, &height);
|
||||||
|
clutter_actor_set_size (box, width - 100, height - 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_MODULE_EXPORT int
|
||||||
|
test_box_layout_main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
ClutterActor *stage, *box;
|
||||||
|
ClutterLayoutManager *layout;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
clutter_init (&argc, &argv);
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
clutter_stage_set_title (CLUTTER_STAGE (stage), "Box Layout");
|
||||||
|
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
|
||||||
|
clutter_actor_set_size (stage, 640, 480);
|
||||||
|
|
||||||
|
layout = clutter_box_layout_new ();
|
||||||
|
|
||||||
|
box = clutter_box_new (layout);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
|
||||||
|
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
add_actor (CLUTTER_BOX_LAYOUT (layout));
|
||||||
|
|
||||||
|
g_signal_connect (stage, "key-release-event",
|
||||||
|
G_CALLBACK (key_release_cb),
|
||||||
|
layout);
|
||||||
|
g_signal_connect (stage, "allocation-changed",
|
||||||
|
G_CALLBACK (stage_size_changed_cb),
|
||||||
|
box);
|
||||||
|
|
||||||
|
clutter_actor_show (stage);
|
||||||
|
|
||||||
|
clutter_main ();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
171
tests/interactive/test-flow-layout.c
Normal file
171
tests/interactive/test-flow-layout.c
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <cairo/cairo.h>
|
||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#define N_RECTS 20
|
||||||
|
|
||||||
|
static gboolean is_homogeneous = FALSE;
|
||||||
|
static gboolean vertical = FALSE;
|
||||||
|
static gboolean random_size = FALSE;
|
||||||
|
|
||||||
|
static gint n_rects = N_RECTS;
|
||||||
|
static gint x_spacing = 0;
|
||||||
|
static gint y_spacing = 0;
|
||||||
|
|
||||||
|
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
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"homogeneous", 'h',
|
||||||
|
0,
|
||||||
|
G_OPTION_ARG_NONE,
|
||||||
|
&is_homogeneous,
|
||||||
|
"Whether the layout should be homogeneous", NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x-spacing", 0,
|
||||||
|
0,
|
||||||
|
G_OPTION_ARG_INT,
|
||||||
|
&x_spacing,
|
||||||
|
"Horizontal spacing between elements", "PX"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"y-spacing", 0,
|
||||||
|
0,
|
||||||
|
G_OPTION_ARG_INT,
|
||||||
|
&y_spacing,
|
||||||
|
"Vertical spacing between elements", "PX"
|
||||||
|
},
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_stage_resize (ClutterActor *stage,
|
||||||
|
const ClutterActorBox *allocation,
|
||||||
|
ClutterAllocationFlags flags,
|
||||||
|
ClutterActor *box)
|
||||||
|
{
|
||||||
|
gfloat width, height;
|
||||||
|
|
||||||
|
clutter_actor_box_get_size (allocation, &width, &height);
|
||||||
|
|
||||||
|
if (vertical)
|
||||||
|
clutter_actor_set_height (box, height);
|
||||||
|
else
|
||||||
|
clutter_actor_set_width (box, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_MODULE_EXPORT int
|
||||||
|
test_flow_layout_main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
ClutterActor *stage, *box;
|
||||||
|
ClutterLayoutManager *layout;
|
||||||
|
ClutterColor stage_color = { 0xe0, 0xf2, 0xfc, 0xff };
|
||||||
|
ClutterColor box_color = { 255, 255, 255, 255 };
|
||||||
|
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_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
|
||||||
|
clutter_actor_set_size (stage, 640, 480);
|
||||||
|
|
||||||
|
layout = clutter_flow_layout_new (vertical ? CLUTTER_FLOW_VERTICAL
|
||||||
|
: CLUTTER_FLOW_HORIZONTAL);
|
||||||
|
clutter_flow_layout_set_homogeneous (CLUTTER_FLOW_LAYOUT (layout),
|
||||||
|
is_homogeneous);
|
||||||
|
clutter_flow_layout_set_column_spacing (CLUTTER_FLOW_LAYOUT (layout),
|
||||||
|
x_spacing);
|
||||||
|
clutter_flow_layout_set_row_spacing (CLUTTER_FLOW_LAYOUT (layout),
|
||||||
|
y_spacing);
|
||||||
|
|
||||||
|
box = clutter_box_new (layout);
|
||||||
|
clutter_box_set_color (CLUTTER_BOX (box), &box_color);
|
||||||
|
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, 224 };
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_connect (stage,
|
||||||
|
"allocation-changed", G_CALLBACK (on_stage_resize),
|
||||||
|
box);
|
||||||
|
|
||||||
|
clutter_actor_show_all (stage);
|
||||||
|
|
||||||
|
clutter_main ();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user