constraints: Add AlignConstraint
AlignConstraint is a simple constraint that keeps an actor's position aligned to the width or height of another actor, multiplied by an alignment factor.
This commit is contained in:
parent
56e8e7d62f
commit
f857457b9d
@ -68,6 +68,7 @@ source_h = \
|
||||
$(srcdir)/clutter-action.h \
|
||||
$(srcdir)/clutter-actor-meta.h \
|
||||
$(srcdir)/clutter-actor.h \
|
||||
$(srcdir)/clutter-align-constraint.h \
|
||||
$(srcdir)/clutter-alpha.h \
|
||||
$(srcdir)/clutter-animatable.h \
|
||||
$(srcdir)/clutter-animation.h \
|
||||
@ -146,6 +147,7 @@ source_c = \
|
||||
$(srcdir)/clutter-action.c \
|
||||
$(srcdir)/clutter-actor-meta.c \
|
||||
$(srcdir)/clutter-actor.c \
|
||||
$(srcdir)/clutter-align-constraint.c \
|
||||
$(srcdir)/clutter-alpha.c \
|
||||
$(srcdir)/clutter-animatable.c \
|
||||
$(srcdir)/clutter-animation.c \
|
||||
|
259
clutter/clutter-align-constraint.c
Normal file
259
clutter/clutter-align-constraint.c
Normal file
@ -0,0 +1,259 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "clutter-align-constraint.h"
|
||||
|
||||
#include "clutter-constraint.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define CLUTTER_ALIGN_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraintClass))
|
||||
#define CLUTTER_IS_ALIGN_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ALIGN_CONSTRAINT))
|
||||
#define CLUTTER_ALIGN_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraintClass))
|
||||
|
||||
typedef struct _ClutterAlignConstraintClass ClutterAlignConstraintClass;
|
||||
|
||||
struct _ClutterAlignConstraint
|
||||
{
|
||||
ClutterConstraint parent_instance;
|
||||
|
||||
ClutterActor *source;
|
||||
ClutterAlignAxis align_axis;
|
||||
gfloat factor;
|
||||
};
|
||||
|
||||
struct _ClutterAlignConstraintClass
|
||||
{
|
||||
ClutterConstraintClass parent_class;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_SOURCE,
|
||||
PROP_ALIGN_AXIS,
|
||||
PROP_FACTOR
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterAlignConstraint,
|
||||
clutter_align_constraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
|
||||
static void
|
||||
update_actor_position (ClutterAlignConstraint *align)
|
||||
{
|
||||
gfloat source_width, source_height;
|
||||
gfloat actor_width, actor_height;
|
||||
ClutterActor *actor;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (align)))
|
||||
return;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (align));
|
||||
if (actor == NULL)
|
||||
return;
|
||||
|
||||
clutter_actor_get_size (align->source, &source_width, &source_height);
|
||||
clutter_actor_get_size (actor, &actor_width, &actor_height);
|
||||
|
||||
switch (align->align_axis)
|
||||
{
|
||||
case CLUTTER_ALIGN_X_AXIS:
|
||||
clutter_actor_set_x (actor, (source_width - actor_width) * align->factor);
|
||||
break;
|
||||
|
||||
case CLUTTER_ALIGN_Y_AXIS:
|
||||
clutter_actor_set_y (actor, (source_height - actor_height) * align->factor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
source_position_changed (GObject *gobject,
|
||||
GParamSpec *pspec,
|
||||
ClutterAlignConstraint *align)
|
||||
{
|
||||
if (strcmp (pspec->name, "width") == 0 ||
|
||||
strcmp (pspec->name, "height") == 0)
|
||||
{
|
||||
update_actor_position (align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
source_destroyed (ClutterActor *actor,
|
||||
ClutterAlignConstraint *align)
|
||||
{
|
||||
align->source = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_align_constraint_set_source (ClutterAlignConstraint *align,
|
||||
ClutterActor *source)
|
||||
{
|
||||
ClutterActor *old_source = align->source;
|
||||
|
||||
if (old_source != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (old_source,
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (old_source,
|
||||
G_CALLBACK (source_position_changed),
|
||||
align);
|
||||
}
|
||||
|
||||
align->source = source;
|
||||
g_signal_connect (align->source, "notify",
|
||||
G_CALLBACK (source_position_changed),
|
||||
align);
|
||||
g_signal_connect (align->source, "destroy",
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
|
||||
update_actor_position (align);
|
||||
|
||||
g_object_notify (G_OBJECT (align), "source");
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
|
||||
ClutterAlignAxis axis)
|
||||
{
|
||||
if (align->align_axis == axis)
|
||||
return;
|
||||
|
||||
align->align_axis = axis;
|
||||
|
||||
update_actor_position (align);
|
||||
|
||||
g_object_notify (G_OBJECT (align), "align-axis");
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
|
||||
gfloat factor)
|
||||
{
|
||||
align->factor = CLAMP (factor, 0.0, 1.0);
|
||||
|
||||
update_actor_position (align);
|
||||
|
||||
g_object_notify (G_OBJECT (align), "factor");
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
_clutter_align_constraint_set_source (align, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_ALIGN_AXIS:
|
||||
_clutter_align_constraint_set_align_axis (align, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
_clutter_align_constraint_set_factor (align, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
g_value_set_object (value, align->source);
|
||||
break;
|
||||
|
||||
case PROP_ALIGN_AXIS:
|
||||
g_value_set_enum (value, align->align_axis);
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
g_value_set_float (value, align->factor);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = clutter_align_constraint_set_property;
|
||||
gobject_class->get_property = clutter_align_constraint_get_property;
|
||||
|
||||
pspec = g_param_spec_object ("source",
|
||||
"Source",
|
||||
"The source of the binding",
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
CLUTTER_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT);
|
||||
g_object_class_install_property (gobject_class, PROP_SOURCE, pspec);
|
||||
|
||||
pspec = g_param_spec_enum ("align-axis",
|
||||
"Align Axis",
|
||||
"The axis to align the position to",
|
||||
CLUTTER_TYPE_ALIGN_AXIS,
|
||||
CLUTTER_ALIGN_X_AXIS,
|
||||
CLUTTER_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT);
|
||||
g_object_class_install_property (gobject_class, PROP_ALIGN_AXIS, pspec);
|
||||
|
||||
pspec = g_param_spec_float ("factor",
|
||||
"Factor",
|
||||
"The alignment factor, between 0.0 and 1.0",
|
||||
0.0, 1.0,
|
||||
0.0,
|
||||
CLUTTER_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT);
|
||||
g_object_class_install_property (gobject_class, PROP_FACTOR, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_init (ClutterAlignConstraint *self)
|
||||
{
|
||||
self->source = NULL;
|
||||
self->align_axis = CLUTTER_ALIGN_X_AXIS;
|
||||
self->factor = 0.0f;
|
||||
}
|
||||
|
||||
ClutterConstraint *
|
||||
clutter_align_constraint_new (ClutterActor *source,
|
||||
ClutterAlignAxis axis,
|
||||
gfloat factor)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (source), NULL);
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_ALIGN_CONSTRAINT,
|
||||
"source", source,
|
||||
"align-axis", axis,
|
||||
"factor", factor,
|
||||
NULL);
|
||||
}
|
31
clutter/clutter-align-constraint.h
Normal file
31
clutter/clutter-align-constraint.h
Normal file
@ -0,0 +1,31 @@
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __CLUTTER_ALIGN_CONSTRAINT_H__
|
||||
#define __CLUTTER_ALIGN_CONSTRAINT_H__
|
||||
|
||||
#include <clutter/clutter-constraint.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ALIGN_CONSTRAINT (clutter_align_constraint_get_type ())
|
||||
#define CLUTTER_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraint))
|
||||
#define CLUTTER_IS_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT))
|
||||
|
||||
typedef struct _ClutterAlignConstraint ClutterAlignConstraint;
|
||||
|
||||
typedef enum { /*< prefix=CLUTTER_ALIGN >*/
|
||||
CLUTTER_ALIGN_X_AXIS,
|
||||
CLUTTER_ALIGN_Y_AXIS,
|
||||
} ClutterAlignAxis;
|
||||
|
||||
GType clutter_align_constraint_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterConstraint *clutter_align_constraint_new (ClutterActor *source,
|
||||
ClutterAlignAxis axis,
|
||||
gfloat factor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ALIGN_CONSTRAINT_H__ */
|
@ -33,6 +33,7 @@
|
||||
#include "clutter-action.h"
|
||||
#include "clutter-actor.h"
|
||||
#include "clutter-actor-meta.h"
|
||||
#include "clutter-align-constraint.h"
|
||||
#include "clutter-alpha.h"
|
||||
#include "clutter-animatable.h"
|
||||
#include "clutter-animation.h"
|
||||
|
@ -72,7 +72,6 @@ test_constraints_main (int argc, char *argv[])
|
||||
clutter_actor_set_reactive (rect, TRUE);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rect);
|
||||
|
||||
#if 0
|
||||
constraint = clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5);
|
||||
clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "x-align");
|
||||
clutter_actor_add_constraint (rect, constraint);
|
||||
@ -80,9 +79,6 @@ test_constraints_main (int argc, char *argv[])
|
||||
constraint = clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5);
|
||||
clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "y-align");
|
||||
clutter_actor_add_constraint (rect, constraint);
|
||||
#else
|
||||
clutter_actor_set_position (rect, (800 - 256) / 2.0, (600 - 256) / 2.0);
|
||||
#endif
|
||||
|
||||
center_rect = rect;
|
||||
|
||||
@ -98,13 +94,9 @@ test_constraints_main (int argc, char *argv[])
|
||||
clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "x-bind");
|
||||
clutter_actor_add_constraint (rect, constraint);
|
||||
|
||||
#if 0
|
||||
constraint = clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5);
|
||||
clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "y-align");
|
||||
clutter_actor_add_constraint (rect, constraint);
|
||||
#else
|
||||
clutter_actor_set_y (rect, (600 - 256) / 2.0);
|
||||
#endif
|
||||
|
||||
left_rect = rect;
|
||||
|
||||
@ -120,13 +112,9 @@ test_constraints_main (int argc, char *argv[])
|
||||
clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "x-bind");
|
||||
clutter_actor_add_constraint (rect, constraint);
|
||||
|
||||
#if 0
|
||||
constraint = clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5);
|
||||
clutter_actor_meta_set_name (CLUTTER_ACTOR_META (constraint), "y-align");
|
||||
clutter_actor_add_constraint (rect, constraint);
|
||||
#else
|
||||
clutter_actor_set_y (rect, (600 - 256) / 2.0);
|
||||
#endif
|
||||
|
||||
right_rect = rect;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user