mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00:00
2006-11-20 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-rectangle.h: * clutter/clutter-rectangle.c: Add border to the ClutterRectangle actor; add "border-width", "border-color" and "has-border" properties, plus their accessors. The border generation code is pretty lame, at the moment. * examples/behave.c: Add code to test the new rectangle properties.
This commit is contained in:
parent
ada4b4e96b
commit
af0d04be7c
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
||||
2006-11-20 Emmanuele Bassi <ebassi@openedhand.com>
|
||||
|
||||
* clutter/clutter-rectangle.h:
|
||||
* clutter/clutter-rectangle.c: Add border to the ClutterRectangle
|
||||
actor; add "border-width", "border-color" and "has-border"
|
||||
properties, plus their accessors. The border generation code is
|
||||
pretty lame, at the moment.
|
||||
|
||||
* examples/behave.c: Add code to test the new rectangle properties.
|
||||
|
||||
2006-11-20 Matthew Allum <mallum@openedhand.com>
|
||||
|
||||
* clutter.doap:
|
||||
|
@ -42,7 +42,11 @@ G_DEFINE_TYPE (ClutterRectangle, clutter_rectangle, CLUTTER_TYPE_ACTOR);
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_COLOR
|
||||
|
||||
PROP_COLOR,
|
||||
PROP_BORDER_COLOR,
|
||||
PROP_BORDER_WIDTH,
|
||||
PROP_HAS_BORDER
|
||||
|
||||
/* FIXME: Add gradient, rounded corner props etc */
|
||||
};
|
||||
@ -53,6 +57,11 @@ enum
|
||||
struct _ClutterRectanglePrivate
|
||||
{
|
||||
ClutterColor color;
|
||||
ClutterColor border_color;
|
||||
|
||||
guint border_width;
|
||||
|
||||
guint has_border : 1;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -72,15 +81,40 @@ clutter_rectangle_paint (ClutterActor *self)
|
||||
|
||||
clutter_actor_get_geometry (self, &geom);
|
||||
|
||||
glColor4ub(priv->color.red,
|
||||
priv->color.green,
|
||||
priv->color.blue,
|
||||
clutter_actor_get_opacity (self));
|
||||
|
||||
/* parent paint call will have translated us into position so
|
||||
* paint from 0,0
|
||||
*/
|
||||
glRecti (0, 0, geom.width, geom.height);
|
||||
* paint from 0, 0
|
||||
*/
|
||||
if (priv->has_border)
|
||||
{
|
||||
glColor4ub (priv->border_color.red,
|
||||
priv->border_color.green,
|
||||
priv->border_color.blue,
|
||||
clutter_actor_get_opacity (self));
|
||||
|
||||
/* this sucks, but it's the only way to make a border */
|
||||
glRecti (0, 0,
|
||||
geom.width, priv->border_width);
|
||||
glRecti (geom.width - priv->border_width, priv->border_width,
|
||||
geom.width, geom.height - priv->border_width);
|
||||
glRecti (0, geom.height - priv->border_width,
|
||||
geom.width, geom.height);
|
||||
glRecti (0, priv->border_width,
|
||||
priv->border_width, geom.height - priv->border_width);
|
||||
|
||||
glColor4ub (priv->color.red,
|
||||
priv->color.green,
|
||||
priv->color.blue,
|
||||
clutter_actor_get_opacity (self));
|
||||
|
||||
glRecti (priv->border_width,
|
||||
priv->border_width,
|
||||
geom.width - priv->border_width,
|
||||
geom.height - priv->border_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
glRecti (0, 0, geom.width, geom.height);
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
@ -100,6 +134,17 @@ clutter_rectangle_set_property (GObject *object,
|
||||
case PROP_COLOR:
|
||||
clutter_rectangle_set_color (rectangle, g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_BORDER_COLOR:
|
||||
clutter_rectangle_set_border_color (rectangle,
|
||||
g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_BORDER_WIDTH:
|
||||
clutter_rectangle_set_border_width (rectangle,
|
||||
g_value_get_uint (value));
|
||||
break;
|
||||
case PROP_HAS_BORDER:
|
||||
rectangle->priv->has_border = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -121,6 +166,16 @@ clutter_rectangle_get_property (GObject *object,
|
||||
clutter_rectangle_get_color (rectangle, &color);
|
||||
g_value_set_boxed (value, &color);
|
||||
break;
|
||||
case PROP_BORDER_COLOR:
|
||||
clutter_rectangle_get_border_color (rectangle, &color);
|
||||
g_value_set_boxed (value, &color);
|
||||
break;
|
||||
case PROP_BORDER_WIDTH:
|
||||
g_value_set_uint (value, rectangle->priv->border_width);
|
||||
break;
|
||||
case PROP_HAS_BORDER:
|
||||
g_value_set_boolean (value, rectangle->priv->has_border);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -154,13 +209,61 @@ clutter_rectangle_class_init (ClutterRectangleClass *klass)
|
||||
gobject_class->set_property = clutter_rectangle_set_property;
|
||||
gobject_class->get_property = clutter_rectangle_get_property;
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class, PROP_COLOR,
|
||||
g_param_spec_boxed ("color",
|
||||
"Color",
|
||||
"The color of the rectangle",
|
||||
CLUTTER_TYPE_COLOR,
|
||||
G_PARAM_READWRITE));
|
||||
/**
|
||||
* ClutterRectangle:color:
|
||||
*
|
||||
* The color of the rectangle.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_COLOR,
|
||||
g_param_spec_boxed ("color",
|
||||
"Color",
|
||||
"The color of the rectangle",
|
||||
CLUTTER_TYPE_COLOR,
|
||||
G_PARAM_READWRITE));
|
||||
/**
|
||||
* ClutterRectangle:border-color:
|
||||
*
|
||||
* The color of the border of the rectangle.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BORDER_COLOR,
|
||||
g_param_spec_boxed ("border-color",
|
||||
"Border Color",
|
||||
"The color of the border of the rectangle",
|
||||
CLUTTER_TYPE_COLOR,
|
||||
G_PARAM_READWRITE));
|
||||
/**
|
||||
* ClutterRectangle:border-width:
|
||||
*
|
||||
* The width of the border of the rectangle, in pixels.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BORDER_WIDTH,
|
||||
g_param_spec_uint ("border-width",
|
||||
"Border Width",
|
||||
"The width of the border of the rectangle",
|
||||
0, G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READWRITE));
|
||||
/**
|
||||
* ClutterRectangle:has-border:
|
||||
*
|
||||
* Whether the #ClutterRectangle should be displayed with a border.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_HAS_BORDER,
|
||||
g_param_spec_boolean ("has-border",
|
||||
"Has Border",
|
||||
"Whether the rectangle should have a border",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (ClutterRectanglePrivate));
|
||||
}
|
||||
@ -168,12 +271,23 @@ clutter_rectangle_class_init (ClutterRectangleClass *klass)
|
||||
static void
|
||||
clutter_rectangle_init (ClutterRectangle *self)
|
||||
{
|
||||
self->priv = CLUTTER_RECTANGLE_GET_PRIVATE (self);
|
||||
ClutterRectanglePrivate *priv;
|
||||
|
||||
self->priv->color.red = 0xff;
|
||||
self->priv->color.green = 0xff;
|
||||
self->priv->color.blue = 0xff;
|
||||
self->priv->color.alpha = 0xff;
|
||||
self->priv = priv = CLUTTER_RECTANGLE_GET_PRIVATE (self);
|
||||
|
||||
priv->color.red = 0xff;
|
||||
priv->color.green = 0xff;
|
||||
priv->color.blue = 0xff;
|
||||
priv->color.alpha = 0xff;
|
||||
|
||||
priv->border_color.red = 0x00;
|
||||
priv->border_color.green = 0x00;
|
||||
priv->border_color.blue = 0x00;
|
||||
priv->border_color.alpha = 0xff;
|
||||
|
||||
priv->border_width = 0;
|
||||
|
||||
priv->has_border = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,6 +360,8 @@ clutter_rectangle_set_color (ClutterRectangle *rectangle,
|
||||
g_return_if_fail (CLUTTER_IS_RECTANGLE (rectangle));
|
||||
g_return_if_fail (color != NULL);
|
||||
|
||||
g_object_ref (rectangle);
|
||||
|
||||
priv = rectangle->priv;
|
||||
|
||||
priv->color.red = color->red;
|
||||
@ -260,4 +376,127 @@ clutter_rectangle_set_color (ClutterRectangle *rectangle,
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (rectangle));
|
||||
|
||||
g_object_notify (G_OBJECT (rectangle), "color");
|
||||
g_object_unref (rectangle);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_rectangle_get_border_width:
|
||||
* @rectangle: a #ClutterRectangle
|
||||
*
|
||||
* Gets the width (in pixels) of the border used by @rectangle
|
||||
*
|
||||
* Return value: the border's width
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
guint
|
||||
clutter_rectangle_get_border_width (ClutterRectangle *rectangle)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_RECTANGLE (rectangle), 0);
|
||||
|
||||
return rectangle->priv->border_width;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_rectangle_set_border_width:
|
||||
* @rectangle: a #ClutterRectangle
|
||||
* @width: the width of the border
|
||||
*
|
||||
* Sets the width (in pixel) of the border used by @rectangle.
|
||||
* A @width of 0 will unset the border.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
void
|
||||
clutter_rectangle_set_border_width (ClutterRectangle *rectangle,
|
||||
guint width)
|
||||
{
|
||||
ClutterRectanglePrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_RECTANGLE (rectangle));
|
||||
priv = rectangle->priv;
|
||||
|
||||
if (priv->border_width != width)
|
||||
{
|
||||
g_object_ref (rectangle);
|
||||
|
||||
priv->border_width = width;
|
||||
|
||||
if (priv->border_width != 0)
|
||||
priv->has_border = TRUE;
|
||||
else
|
||||
priv->has_border = FALSE;
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (rectangle)))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (rectangle));
|
||||
|
||||
g_object_notify (G_OBJECT (rectangle), "border-width");
|
||||
g_object_notify (G_OBJECT (rectangle), "has-border");
|
||||
g_object_unref (rectangle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_rectangle_get_border_color:
|
||||
* @rectangle: a #ClutterRectangle
|
||||
* @color: return location for a #ClutterColor
|
||||
*
|
||||
* Gets the color of the border used by @rectangle and places
|
||||
* it into @color.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
void
|
||||
clutter_rectangle_get_border_color (ClutterRectangle *rectangle,
|
||||
ClutterColor *color)
|
||||
{
|
||||
ClutterRectanglePrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_RECTANGLE (rectangle));
|
||||
g_return_if_fail (color != NULL);
|
||||
|
||||
priv = rectangle->priv;
|
||||
|
||||
color->red = priv->border_color.red;
|
||||
color->green = priv->border_color.green;
|
||||
color->blue = priv->border_color.blue;
|
||||
color->alpha = priv->border_color.alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_rectangle_set_border_color:
|
||||
* @rectangle: a #ClutterRectangle
|
||||
* @color: the color of the border
|
||||
*
|
||||
* Sets the color of the border used by @rectangle using @color
|
||||
*/
|
||||
void
|
||||
clutter_rectangle_set_border_color (ClutterRectangle *rectangle,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
ClutterRectanglePrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_RECTANGLE (rectangle));
|
||||
g_return_if_fail (color != NULL);
|
||||
|
||||
priv = rectangle->priv;
|
||||
|
||||
if (priv->border_color.red != color->red &&
|
||||
priv->border_color.green != color->green &&
|
||||
priv->border_color.blue != color->blue &&
|
||||
priv->border_color.alpha != color->alpha)
|
||||
{
|
||||
g_object_ref (rectangle);
|
||||
|
||||
priv->border_color.red = color->red;
|
||||
priv->border_color.green = color->green;
|
||||
priv->border_color.blue = color->blue;
|
||||
priv->border_color.alpha = color->alpha;
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (rectangle)))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (rectangle));
|
||||
|
||||
g_object_notify (G_OBJECT (rectangle), "border-color");
|
||||
g_object_unref (rectangle);
|
||||
}
|
||||
}
|
||||
|
@ -79,13 +79,20 @@ struct _ClutterRectangleClass
|
||||
|
||||
GType clutter_rectangle_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor *clutter_rectangle_new (void);
|
||||
ClutterActor *clutter_rectangle_new_with_color (const ClutterColor *color);
|
||||
ClutterActor *clutter_rectangle_new (void);
|
||||
ClutterActor *clutter_rectangle_new_with_color (const ClutterColor *color);
|
||||
|
||||
void clutter_rectangle_get_color (ClutterRectangle *rectangle,
|
||||
ClutterColor *color);
|
||||
void clutter_rectangle_set_color (ClutterRectangle *rectangle,
|
||||
void clutter_rectangle_get_color (ClutterRectangle *rectangle,
|
||||
ClutterColor *color);
|
||||
void clutter_rectangle_set_color (ClutterRectangle *rectangle,
|
||||
const ClutterColor *color);
|
||||
guint clutter_rectangle_get_border_width (ClutterRectangle *rectangle);
|
||||
void clutter_rectangle_set_border_width (ClutterRectangle *rectangle,
|
||||
guint width);
|
||||
void clutter_rectangle_get_border_color (ClutterRectangle *rectangle,
|
||||
ClutterColor *color);
|
||||
void clutter_rectangle_set_border_color (ClutterRectangle *rectangle,
|
||||
const ClutterColor *color);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -165,6 +165,10 @@ clutter_rectangle_new
|
||||
clutter_rectangle_new_with_color
|
||||
clutter_rectangle_get_color
|
||||
clutter_rectangle_set_color
|
||||
clutter_rectangle_get_border_color
|
||||
clutter_rectangle_set_border_color
|
||||
clutter_rectangle_get_border_width
|
||||
clutter_rectangle_set_border_width
|
||||
<SUBSECTION Standard>
|
||||
CLUTTER_RECTANGLE
|
||||
CLUTTER_IS_RECTANGLE
|
||||
|
@ -23,11 +23,26 @@ ClutterRectangle
|
||||
</para>
|
||||
|
||||
|
||||
<!-- ##### ARG ClutterRectangle:border-color ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG ClutterRectangle:border-width ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG ClutterRectangle:color ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG ClutterRectangle:has-border ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### STRUCT ClutterRectangleClass ##### -->
|
||||
<para>
|
||||
|
||||
@ -74,3 +89,39 @@ ClutterRectangle
|
||||
@color:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION clutter_rectangle_get_border_color ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@rectangle:
|
||||
@color:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION clutter_rectangle_set_border_color ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@rectangle:
|
||||
@color:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION clutter_rectangle_get_border_width ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@rectangle:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION clutter_rectangle_set_border_width ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@rectangle:
|
||||
@width:
|
||||
|
||||
|
||||
|
@ -6,16 +6,22 @@ main (int argc, char *argv[])
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
ClutterBehaviour *behave;
|
||||
ClutterActor *stage, *hand;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *group, *rect, *hand;
|
||||
ClutterColor stage_color = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||
ClutterColor rect_bg_color = { 0x33, 0x22, 0x22, 0xff };
|
||||
ClutterColor rect_border_color = { 0xff, 0xcc, 0xcc, 0xff };
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
ClutterKnot knots[] = {{ 100, 100 }, { 100, 200 }, { 200, 200 },
|
||||
{ 200, 100 }, {100, 100 }};
|
||||
ClutterKnot knots[] = {{ 0, 0 }, { 0, 300 }, { 300, 300 },
|
||||
{ 300, 0 }, {0, 0 }};
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
g_signal_connect (stage, "key-press-event",
|
||||
G_CALLBACK (clutter_main_quit),
|
||||
NULL);
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_file ("redhand.png", NULL);
|
||||
|
||||
@ -26,12 +32,30 @@ main (int argc, char *argv[])
|
||||
&stage_color);
|
||||
|
||||
/* Make a hand */
|
||||
group = clutter_group_new ();
|
||||
clutter_group_add (CLUTTER_GROUP (stage), group);
|
||||
clutter_actor_show (group);
|
||||
|
||||
rect = clutter_rectangle_new ();
|
||||
clutter_actor_set_position (rect, 0, 0);
|
||||
clutter_actor_set_size (rect,
|
||||
gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf));
|
||||
clutter_rectangle_set_color (CLUTTER_RECTANGLE (rect),
|
||||
&rect_bg_color);
|
||||
clutter_rectangle_set_border_width (CLUTTER_RECTANGLE (rect), 10);
|
||||
clutter_rectangle_set_border_color (CLUTTER_RECTANGLE (rect),
|
||||
&rect_border_color);
|
||||
clutter_actor_show (rect);
|
||||
|
||||
hand = clutter_texture_new_from_pixbuf (pixbuf);
|
||||
clutter_actor_set_position (hand, 100, 100);
|
||||
clutter_group_add (CLUTTER_GROUP (stage), hand);
|
||||
clutter_actor_set_position (hand, 0, 0);
|
||||
clutter_actor_show (hand);
|
||||
|
||||
clutter_group_add_many (CLUTTER_GROUP (group), rect, hand, NULL);
|
||||
|
||||
/* Make a timeline */
|
||||
timeline = clutter_timeline_new (100, 60); /* num frames, fps */
|
||||
timeline = clutter_timeline_new (100, 26); /* num frames, fps */
|
||||
g_object_set (timeline, "loop", TRUE, 0);
|
||||
|
||||
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
|
||||
@ -43,11 +67,11 @@ main (int argc, char *argv[])
|
||||
behave = clutter_behaviour_opacity_new (alpha, 0X33, 0xff);
|
||||
|
||||
/* Apply it to our actor */
|
||||
clutter_behaviour_apply (behave, hand);
|
||||
clutter_behaviour_apply (behave, group);
|
||||
|
||||
/* Make a path behaviour and apply that too */
|
||||
behave = clutter_behaviour_path_new (alpha, knots, 5);
|
||||
clutter_behaviour_apply (behave, hand);
|
||||
clutter_behaviour_apply (behave, group);
|
||||
|
||||
/* start the timeline and thus the animations */
|
||||
clutter_timeline_start (timeline);
|
||||
|
Loading…
Reference in New Issue
Block a user