mirror of
https://github.com/brl/mutter.git
synced 2025-02-28 10:44:09 +00:00
[layout] Add layers to BinLayout
Each actor managed by a BinLayout policy should reside inside its own "layer", with horizontal and vertical alignment. The :x-align and :y-align properties of the BinLayout are the default alignment policies, which are copied to each new "layer" when it is created. The set_alignment() and get_alignment() methods of BinLayout can be changed to operate on a specific "layer". The whole machinery uses the new ChildMeta support inside the LayoutManager base abstract class.
This commit is contained in:
parent
98474076a1
commit
9cccff504a
@ -40,12 +40,20 @@
|
|||||||
#include "clutter-actor.h"
|
#include "clutter-actor.h"
|
||||||
#include "clutter-animatable.h"
|
#include "clutter-animatable.h"
|
||||||
#include "clutter-bin-layout.h"
|
#include "clutter-bin-layout.h"
|
||||||
|
#include "clutter-child-meta.h"
|
||||||
#include "clutter-debug.h"
|
#include "clutter-debug.h"
|
||||||
#include "clutter-enum-types.h"
|
#include "clutter-enum-types.h"
|
||||||
#include "clutter-private.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))
|
#define CLUTTER_BIN_LAYOUT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayoutPrivate))
|
||||||
|
|
||||||
|
typedef struct _ClutterBinLayer ClutterBinLayer;
|
||||||
|
typedef struct _ClutterChildMetaClass ClutterBinLayerClass;
|
||||||
|
|
||||||
struct _ClutterBinLayoutPrivate
|
struct _ClutterBinLayoutPrivate
|
||||||
{
|
{
|
||||||
ClutterBinAlignment x_align;
|
ClutterBinAlignment x_align;
|
||||||
@ -55,6 +63,24 @@ struct _ClutterBinLayoutPrivate
|
|||||||
gdouble y_factor;
|
gdouble y_factor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _ClutterBinLayer
|
||||||
|
{
|
||||||
|
ClutterChildMeta parent_instance;
|
||||||
|
|
||||||
|
ClutterBinLayout *layout;
|
||||||
|
|
||||||
|
ClutterBinAlignment x_align;
|
||||||
|
ClutterBinAlignment y_align;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_LAYER_0,
|
||||||
|
|
||||||
|
PROP_LAYER_X_ALIGN,
|
||||||
|
PROP_LAYER_Y_ALIGN
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -63,11 +89,146 @@ enum
|
|||||||
PROP_Y_ALIGN
|
PROP_Y_ALIGN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ClutterBinLayer,
|
||||||
|
clutter_bin_layer,
|
||||||
|
CLUTTER_TYPE_CHILD_META);
|
||||||
|
|
||||||
G_DEFINE_TYPE (ClutterBinLayout,
|
G_DEFINE_TYPE (ClutterBinLayout,
|
||||||
clutter_bin_layout,
|
clutter_bin_layout,
|
||||||
CLUTTER_TYPE_LAYOUT_MANAGER);
|
CLUTTER_TYPE_LAYOUT_MANAGER);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ClutterBinLayer
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_layer_x_align (ClutterBinLayer *self,
|
||||||
|
ClutterBinAlignment alignment)
|
||||||
|
{
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
|
||||||
|
if (self->x_align == alignment)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->x_align = alignment;
|
||||||
|
|
||||||
|
g_assert (self->layout != NULL);
|
||||||
|
manager = CLUTTER_LAYOUT_MANAGER (self->layout);
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (self->y_align == alignment)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->y_align = alignment;
|
||||||
|
|
||||||
|
g_assert (self->layout != NULL);
|
||||||
|
manager = CLUTTER_LAYOUT_MANAGER (self->layout);
|
||||||
|
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",
|
||||||
|
"X Align",
|
||||||
|
"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",
|
||||||
|
"Y Align",
|
||||||
|
"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
|
static void
|
||||||
set_x_align (ClutterBinLayout *self,
|
set_x_align (ClutterBinLayout *self,
|
||||||
ClutterBinAlignment alignment)
|
ClutterBinAlignment alignment)
|
||||||
@ -200,7 +361,6 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
|||||||
const ClutterActorBox *allocation,
|
const ClutterActorBox *allocation,
|
||||||
ClutterAllocationFlags flags)
|
ClutterAllocationFlags flags)
|
||||||
{
|
{
|
||||||
ClutterBinLayoutPrivate *priv = CLUTTER_BIN_LAYOUT (manager)->priv;
|
|
||||||
GList *children = clutter_container_get_children (container);
|
GList *children = clutter_container_get_children (container);
|
||||||
GList *l;
|
GList *l;
|
||||||
gfloat available_w, available_h;
|
gfloat available_w, available_h;
|
||||||
@ -211,17 +371,24 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
|||||||
for (l = children; l != NULL; l = l->next)
|
for (l = children; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
ClutterActor *child = l->data;
|
ClutterActor *child = l->data;
|
||||||
|
ClutterChildMeta *meta;
|
||||||
|
ClutterBinLayer *layer;
|
||||||
ClutterActorBox child_alloc = { 0, };
|
ClutterActorBox child_alloc = { 0, };
|
||||||
gfloat child_width, child_height;
|
gfloat child_width, child_height;
|
||||||
ClutterRequestMode request;
|
ClutterRequestMode request;
|
||||||
|
|
||||||
if (priv->x_align == CLUTTER_BIN_ALIGNMENT_FILL)
|
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 = (int) 0;
|
child_alloc.x1 = (int) 0;
|
||||||
child_alloc.x2 = (int) available_w;
|
child_alloc.x2 = (int) available_w;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->y_align == CLUTTER_BIN_ALIGNMENT_FILL)
|
if (layer->y_align == CLUTTER_BIN_ALIGNMENT_FILL)
|
||||||
{
|
{
|
||||||
child_alloc.y1 = (int) 0;
|
child_alloc.y1 = (int) 0;
|
||||||
child_alloc.y2 = (int) available_h;
|
child_alloc.y2 = (int) available_h;
|
||||||
@ -230,11 +397,11 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
|||||||
/* if we are filling horizontally and vertically then we
|
/* if we are filling horizontally and vertically then we
|
||||||
* can break here because we already have a full allocation
|
* can break here because we already have a full allocation
|
||||||
*/
|
*/
|
||||||
if (priv->x_align == CLUTTER_BIN_ALIGNMENT_FILL &&
|
if (layer->x_align == CLUTTER_BIN_ALIGNMENT_FILL &&
|
||||||
priv->y_align == CLUTTER_BIN_ALIGNMENT_FILL)
|
layer->y_align == CLUTTER_BIN_ALIGNMENT_FILL)
|
||||||
{
|
{
|
||||||
clutter_actor_allocate (child, &child_alloc, flags);
|
clutter_actor_allocate (child, &child_alloc, flags);
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
request = CLUTTER_REQUEST_HEIGHT_FOR_WIDTH;
|
request = CLUTTER_REQUEST_HEIGHT_FOR_WIDTH;
|
||||||
@ -270,32 +437,32 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
|||||||
child_width = CLAMP (nat_width, min_width, available_w);
|
child_width = CLAMP (nat_width, min_width, available_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->x_align == CLUTTER_BIN_ALIGNMENT_FIXED)
|
if (layer->x_align == CLUTTER_BIN_ALIGNMENT_FIXED)
|
||||||
{
|
{
|
||||||
child_alloc.x1 = (int) clutter_actor_get_x (child);
|
child_alloc.x1 = (int) clutter_actor_get_x (child);
|
||||||
child_alloc.x2 = (int) child_alloc.x1 + child_width;
|
child_alloc.x2 = (int) child_alloc.x1 + child_width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gdouble x_align = get_bin_alignment_factor (priv->x_align);
|
gdouble x_align = get_bin_alignment_factor (layer->x_align);
|
||||||
|
|
||||||
if (priv->x_align != CLUTTER_BIN_ALIGNMENT_FILL)
|
if (layer->x_align != CLUTTER_BIN_ALIGNMENT_FILL)
|
||||||
{
|
{
|
||||||
child_alloc.x1 = (int) ((available_w - child_width) * x_align);
|
child_alloc.x1 = (int) ((available_w - child_width) * x_align);
|
||||||
child_alloc.x2 = (int) child_alloc.x1 + child_width;
|
child_alloc.x2 = (int) child_alloc.x1 + child_width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->y_align == CLUTTER_BIN_ALIGNMENT_FIXED)
|
if (layer->y_align == CLUTTER_BIN_ALIGNMENT_FIXED)
|
||||||
{
|
{
|
||||||
child_alloc.y1 = (int) clutter_actor_get_y (child);
|
child_alloc.y1 = (int) clutter_actor_get_y (child);
|
||||||
child_alloc.y2 = (int) child_alloc.y1 + child_height;
|
child_alloc.y2 = (int) child_alloc.y1 + child_height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gdouble y_align = get_bin_alignment_factor (priv->y_align);
|
gdouble y_align = get_bin_alignment_factor (layer->y_align);
|
||||||
|
|
||||||
if (priv->y_align != CLUTTER_BIN_ALIGNMENT_FILL)
|
if (layer->y_align != CLUTTER_BIN_ALIGNMENT_FILL)
|
||||||
{
|
{
|
||||||
child_alloc.y1 = (int) ((available_h - child_height) * y_align);
|
child_alloc.y1 = (int) ((available_h - child_height) * y_align);
|
||||||
child_alloc.y2 = (int) child_alloc.y1 + child_height;
|
child_alloc.y2 = (int) child_alloc.y1 + child_height;
|
||||||
@ -308,6 +475,28 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
|||||||
g_list_free (children);
|
g_list_free (children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClutterChildMeta *
|
||||||
|
clutter_bin_layout_create_child_meta (ClutterLayoutManager *manager,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterBinLayoutPrivate *priv;
|
||||||
|
ClutterChildMeta *meta;
|
||||||
|
|
||||||
|
priv = CLUTTER_BIN_LAYOUT (manager)->priv;
|
||||||
|
|
||||||
|
meta = g_object_new (CLUTTER_TYPE_BIN_LAYER,
|
||||||
|
"container", container,
|
||||||
|
"actor", actor,
|
||||||
|
"x-align", priv->x_align,
|
||||||
|
"y_align", priv->y_align,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
CLUTTER_BIN_LAYER (meta)->layout = CLUTTER_BIN_LAYOUT (manager);
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_bin_layout_set_property (GObject *gobject,
|
clutter_bin_layout_set_property (GObject *gobject,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -411,6 +600,8 @@ clutter_bin_layout_class_init (ClutterBinLayoutClass *klass)
|
|||||||
clutter_bin_layout_get_preferred_height;
|
clutter_bin_layout_get_preferred_height;
|
||||||
layout_class->allocate =
|
layout_class->allocate =
|
||||||
clutter_bin_layout_allocate;
|
clutter_bin_layout_allocate;
|
||||||
|
layout_class->create_child_meta =
|
||||||
|
clutter_bin_layout_create_child_meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -424,9 +615,9 @@ clutter_bin_layout_init (ClutterBinLayout *self)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_bin_layout_new:
|
* clutter_bin_layout_new:
|
||||||
* @x_align: the #ClutterBinAlignment policy to be used on the
|
* @x_align: the default alignment policy to be used on the
|
||||||
* horizontal axis
|
* horizontal axis
|
||||||
* @y_align: the #ClutterBinAlignment policy to be used on the
|
* @y_align: the default alignment policy to be used on the
|
||||||
* vertical axis
|
* vertical axis
|
||||||
*
|
*
|
||||||
* Creates a new #ClutterBinLayout layout manager
|
* Creates a new #ClutterBinLayout layout manager
|
||||||
@ -448,29 +639,39 @@ clutter_bin_layout_new (ClutterBinAlignment x_align,
|
|||||||
/**
|
/**
|
||||||
* clutter_bin_layout_set_alignment:
|
* clutter_bin_layout_set_alignment:
|
||||||
* @self: a #ClutterBinLayout
|
* @self: a #ClutterBinLayout
|
||||||
* @x_align: the #ClutterBinAlignment policy to be used on the
|
* @container: a #ClutterContainer with a layout managed by @self
|
||||||
* horizontal axis
|
* @child: a #ClutterActor child of @container
|
||||||
* @y_align: the #ClutterBinAlignment policy to be used on the
|
* @x_align: the horizontal alignment policy to be used for the @child
|
||||||
* vertical axis
|
* inside @container
|
||||||
|
* @y_align: the vertical aligment policy to be used on the @child
|
||||||
|
* inside @container
|
||||||
*
|
*
|
||||||
* Sets the alignment policies on the horizontal and vertical
|
* Sets the horizontal and vertical alignment policies to be applied
|
||||||
* axis for @self
|
* to the @child of @container
|
||||||
*
|
*
|
||||||
* Since: 1.2
|
* Since: 1.2
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clutter_bin_layout_set_alignment (ClutterBinLayout *self,
|
clutter_bin_layout_set_alignment (ClutterBinLayout *self,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *child,
|
||||||
ClutterBinAlignment x_align,
|
ClutterBinAlignment x_align,
|
||||||
ClutterBinAlignment y_align)
|
ClutterBinAlignment y_align)
|
||||||
{
|
{
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
ClutterChildMeta *meta;
|
||||||
|
ClutterBinLayer *layer;
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
|
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
|
||||||
|
|
||||||
g_object_freeze_notify (G_OBJECT (self));
|
manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||||
|
meta = clutter_layout_manager_get_child_meta (manager, container, child);
|
||||||
|
g_return_if_fail (CLUTTER_IS_BIN_LAYER (meta));
|
||||||
|
|
||||||
set_x_align (self, x_align);
|
layer = CLUTTER_BIN_LAYER (meta);
|
||||||
set_y_align (self, y_align);
|
|
||||||
|
|
||||||
g_object_thaw_notify (G_OBJECT (self));
|
set_layer_x_align (layer, x_align);
|
||||||
|
set_layer_y_align (layer, y_align);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -487,14 +688,26 @@ clutter_bin_layout_set_alignment (ClutterBinLayout *self,
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clutter_bin_layout_get_alignment (ClutterBinLayout *self,
|
clutter_bin_layout_get_alignment (ClutterBinLayout *self,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *child,
|
||||||
ClutterBinAlignment *x_align,
|
ClutterBinAlignment *x_align,
|
||||||
ClutterBinAlignment *y_align)
|
ClutterBinAlignment *y_align)
|
||||||
{
|
{
|
||||||
|
ClutterLayoutManager *manager;
|
||||||
|
ClutterChildMeta *meta;
|
||||||
|
ClutterBinLayer *layer;
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
|
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
|
||||||
|
|
||||||
|
manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||||
|
meta = clutter_layout_manager_get_child_meta (manager, container, child);
|
||||||
|
g_return_if_fail (CLUTTER_IS_BIN_LAYER (meta));
|
||||||
|
|
||||||
|
layer = CLUTTER_BIN_LAYER (meta);
|
||||||
|
|
||||||
if (x_align)
|
if (x_align)
|
||||||
*x_align = self->priv->x_align;
|
*x_align = layer->x_align;
|
||||||
|
|
||||||
if (y_align)
|
if (y_align)
|
||||||
*y_align = self->priv->y_align;
|
*y_align = layer->y_align;
|
||||||
}
|
}
|
||||||
|
@ -81,9 +81,13 @@ ClutterLayoutManager *clutter_bin_layout_new (ClutterBinAlignment ali
|
|||||||
ClutterBinAlignment align_y);
|
ClutterBinAlignment align_y);
|
||||||
|
|
||||||
void clutter_bin_layout_set_alignment (ClutterBinLayout *self,
|
void clutter_bin_layout_set_alignment (ClutterBinLayout *self,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *child,
|
||||||
ClutterBinAlignment x_align,
|
ClutterBinAlignment x_align,
|
||||||
ClutterBinAlignment y_align);
|
ClutterBinAlignment y_align);
|
||||||
void clutter_bin_layout_get_alignment (ClutterBinLayout *self,
|
void clutter_bin_layout_get_alignment (ClutterBinLayout *self,
|
||||||
|
ClutterContainer *container,
|
||||||
|
ClutterActor *child,
|
||||||
ClutterBinAlignment *x_align,
|
ClutterBinAlignment *x_align,
|
||||||
ClutterBinAlignment *y_align);
|
ClutterBinAlignment *y_align);
|
||||||
|
|
||||||
|
@ -1,12 +1,101 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
|
#include <cairo/cairo.h>
|
||||||
#include <clutter/clutter.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
|
G_MODULE_EXPORT int
|
||||||
test_box_main (int argc, char *argv[])
|
test_box_main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
ClutterActor *stage, *box, *rect;
|
ClutterActor *stage, *box, *rect;
|
||||||
ClutterLayoutManager *layout;
|
ClutterLayoutManager *layout;
|
||||||
|
ClutterColor stage_color = { 0xe0, 0xf2, 0xfc, 0xff };
|
||||||
ClutterColor bg_color = { 0xcc, 0xcc, 0xcc, 0x99 };
|
ClutterColor bg_color = { 0xcc, 0xcc, 0xcc, 0x99 };
|
||||||
ClutterColor *color;
|
ClutterColor *color;
|
||||||
|
|
||||||
@ -14,7 +103,8 @@ test_box_main (int argc, char *argv[])
|
|||||||
|
|
||||||
stage = clutter_stage_get_default ();
|
stage = clutter_stage_get_default ();
|
||||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Box test");
|
clutter_stage_set_title (CLUTTER_STAGE (stage), "Box test");
|
||||||
clutter_actor_set_size (stage, 320, 200);
|
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,
|
layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
CLUTTER_BIN_ALIGNMENT_CENTER);
|
CLUTTER_BIN_ALIGNMENT_CENTER);
|
||||||
@ -22,20 +112,67 @@ test_box_main (int argc, char *argv[])
|
|||||||
box = clutter_box_new (layout);
|
box = clutter_box_new (layout);
|
||||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), box);
|
||||||
clutter_actor_set_anchor_point_from_gravity (box, CLUTTER_GRAVITY_CENTER);
|
clutter_actor_set_anchor_point_from_gravity (box, CLUTTER_GRAVITY_CENTER);
|
||||||
clutter_actor_set_position (box, 160, 100);
|
clutter_actor_set_position (box, 320, 240);
|
||||||
|
clutter_actor_set_reactive (box, TRUE);
|
||||||
|
clutter_actor_set_name (box, "box");
|
||||||
|
|
||||||
rect = clutter_rectangle_new_with_color (&bg_color);
|
rect = make_background (&bg_color, 200, 200);
|
||||||
clutter_container_add_actor (CLUTTER_CONTAINER (box), rect);
|
clutter_container_add_actor (CLUTTER_CONTAINER (box), rect);
|
||||||
clutter_actor_set_size (rect, 100, 100);
|
clutter_actor_lower_bottom (rect);
|
||||||
|
clutter_actor_set_name (rect, "background");
|
||||||
|
|
||||||
|
clutter_bin_layout_set_alignment (CLUTTER_BIN_LAYOUT (layout),
|
||||||
|
CLUTTER_CONTAINER (box),
|
||||||
|
rect,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_FILL,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_FILL);
|
||||||
|
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
clutter_container_add_actor (CLUTTER_CONTAINER (box), tex);
|
||||||
|
clutter_actor_raise (tex, rect);
|
||||||
|
clutter_actor_set_width (tex, 175);
|
||||||
|
clutter_actor_set_name (tex, "texture");
|
||||||
|
|
||||||
|
clutter_bin_layout_set_alignment (CLUTTER_BIN_LAYOUT (layout),
|
||||||
|
CLUTTER_CONTAINER (box),
|
||||||
|
tex,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
color = clutter_color_new (g_random_int_range (0, 255),
|
color = clutter_color_new (g_random_int_range (0, 255),
|
||||||
g_random_int_range (0, 255),
|
g_random_int_range (0, 255),
|
||||||
g_random_int_range (0, 255),
|
g_random_int_range (0, 255),
|
||||||
255);
|
224);
|
||||||
|
|
||||||
rect = clutter_rectangle_new_with_color (color);
|
rect = clutter_rectangle_new_with_color (color);
|
||||||
clutter_container_add_actor (CLUTTER_CONTAINER (box), rect);
|
clutter_container_add_actor (CLUTTER_CONTAINER (box), rect);
|
||||||
clutter_actor_set_size (rect, 50, 50);
|
clutter_actor_set_size (rect, 50, 50);
|
||||||
|
clutter_actor_set_opacity (rect, 0);
|
||||||
|
clutter_actor_raise_top (rect);
|
||||||
|
clutter_actor_set_name (rect, "emblem");
|
||||||
|
|
||||||
|
clutter_bin_layout_set_alignment (CLUTTER_BIN_LAYOUT (layout),
|
||||||
|
CLUTTER_CONTAINER (box),
|
||||||
|
rect,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_END,
|
||||||
|
CLUTTER_BIN_ALIGNMENT_END);
|
||||||
|
|
||||||
|
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_actor_show_all (stage);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user