2008-02-20 Emmanuele Bassi <ebassi@openedhand.com>

* clutter/clutter-actor.h:
	* clutter/clutter-actor.c:
	(clutter_actor_get_abs_opacity): Add function that does what
	get_opacity() does now...

	(clutter_actor_get_opacity): ... and make get_opacity() do what
	it's supposed to be doing. The original get_opacity() returned
	a composited value, and there's no way to actually extract the
	real opacity value set with set_opacity().

	* clutter/clutter-clone-texture.c:
	* clutter/clutter-rectangle.c:
	* clutter/clutter-texture.c: Update to use get_abs_opacity().

	* clutter/clutter-entry.c:
	* clutter/clutter-label.c: Ditto. Also, never change the stored
	alpha value. (#804)

	* tests/Makefile.am:
	* tests/test-opacity.c: Test suite for the get_opacity() and
	get_abs_opacity() API, and correct opacity handling.

	* README: Add note about the change in get_opacity().
This commit is contained in:
Emmanuele Bassi 2008-02-20 10:59:47 +00:00
parent 015eba286f
commit 8c451b8a67
11 changed files with 215 additions and 21 deletions

View File

@ -1,3 +1,29 @@
2008-02-20 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-actor.h:
* clutter/clutter-actor.c:
(clutter_actor_get_abs_opacity): Add function that does what
get_opacity() does now...
(clutter_actor_get_opacity): ... and make get_opacity() do what
it's supposed to be doing. The original get_opacity() returned
a composited value, and there's no way to actually extract the
real opacity value set with set_opacity().
* clutter/clutter-clone-texture.c:
* clutter/clutter-rectangle.c:
* clutter/clutter-texture.c: Update to use get_abs_opacity().
* clutter/clutter-entry.c:
* clutter/clutter-label.c: Ditto. Also, never change the stored
alpha value. (#804)
* tests/Makefile.am:
* tests/test-opacity.c: Test suite for the get_opacity() and
get_abs_opacity() API, and correct opacity handling.
* README: Add note about the change in get_opacity().
2008-02-19 Chris Lord <chris@openedhand.com> 2008-02-19 Chris Lord <chris@openedhand.com>
* clutter/clutter-model.c: (clutter_model_resort): * clutter/clutter-model.c: (clutter_model_resort):

13
README
View File

@ -140,7 +140,7 @@ RELEASE NOTES
Relevant information for developers with existing Clutter applications Relevant information for developers with existing Clutter applications
wanting to port to newer releases (See NEWS for general new feature info). wanting to port to newer releases (See NEWS for general new feature info).
Release Notes for Clutter 0.6.0 Release Notes for Clutter 0.6
------------------------------- -------------------------------
* Now that every actor has events, the class signal handlers have been * Now that every actor has events, the class signal handlers have been
@ -229,6 +229,17 @@ Release Notes for Clutter 0.6.0
clutter_entry_set_cursor_position() and clutter_entry_get_cursor_position() clutter_entry_set_cursor_position() and clutter_entry_get_cursor_position()
respectively. respectively.
* The behaviour of clutter_actor_get_opacity() has been slightly changed;
instead of returning the composited opacity of the entire parents chain
of an actor, clutter_actor_get_opacity() does what you mean, and returns
the opacity set with clutter_actor_set_opacity(). The composited
opacity value is now returned by clutter_actor_get_abs_opacity().
* Until 0.6.0, clutter_label_get_color() would have returned a ClutterColor
with the alpha component equal to the composited opacity of the label.
Now, clutter_label_get_color() returns a copy of the exact color set
with clutter_label_set_color().
Release Notes for Clutter 0.4.0 Release Notes for Clutter 0.4.0
------------------------------- -------------------------------

View File

@ -3345,25 +3345,61 @@ clutter_actor_set_opacity (ClutterActor *self,
} }
/** /**
* clutter_actor_get_opacity: * clutter_actor_get_abs_opacity:
* @self: A #ClutterActor * @self: A #ClutterActor
* *
* Retrieves the actor's opacity. * Retrieves the absolute opacity of the actor, as it appears on the stage.
*
* This function traverses the hierarchy chain and composites the opacity of
* the actor with that of its parents.
*
* This function is intended for subclasses to use in the paint virtual
* function, to paint themselves with the correct opacity.
* *
* Return value: The actor opacity value. * Return value: The actor opacity value.
*
* Since: 0.6
*/ */
guint8 guint8
clutter_actor_get_opacity (ClutterActor *self) clutter_actor_get_abs_opacity (ClutterActor *self)
{ {
ClutterActorPrivate *priv;
ClutterActor *parent; ClutterActor *parent;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0); g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0);
parent = self->priv->parent_actor; priv = self->priv;
parent = priv->parent_actor;
/* Factor in the actual actors opacity with parents */ /* Factor in the actual actors opacity with parents */
if (parent && clutter_actor_get_opacity (parent) != 0xff) if (G_LIKELY (parent))
return (clutter_actor_get_opacity(parent) * self->priv->opacity) / 0xff; {
guint8 opacity = clutter_actor_get_abs_opacity (parent);
if (opacity != 0xff)
return (opacity * priv->opacity) / 0xff;
}
return clutter_actor_get_opacity (self);
}
/**
* clutter_actor_get_opacity:
* @self: a #ClutterActor
*
* Retrieves the opacity value of an actor, as set by
* clutter_actor_set_opacity().
*
* For retrieving the absolute opacity of the actor inside a paint
* virtual function, see clutter_actor_get_abs_opacity().
*
* Return value: the opacity of the actor
*/
guint8
clutter_actor_get_opacity (ClutterActor *self)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0);
return self->priv->opacity; return self->priv->opacity;
} }

View File

@ -360,6 +360,7 @@ ClutterFixed clutter_actor_get_rotationx (ClutterActor
void clutter_actor_set_opacity (ClutterActor *self, void clutter_actor_set_opacity (ClutterActor *self,
guint8 opacity); guint8 opacity);
guint8 clutter_actor_get_opacity (ClutterActor *self); guint8 clutter_actor_get_opacity (ClutterActor *self);
guint8 clutter_actor_get_abs_opacity (ClutterActor *self);
void clutter_actor_set_name (ClutterActor *self, void clutter_actor_set_name (ClutterActor *self,
const gchar *name); const gchar *name);
G_CONST_RETURN gchar *clutter_actor_get_name (ClutterActor *self); G_CONST_RETURN gchar *clutter_actor_get_name (ClutterActor *self);

View File

@ -213,7 +213,7 @@ clutter_clone_texture_paint (ClutterActor *self)
cogl_enable (CGL_ENABLE_TEXTURE_2D|CGL_ENABLE_BLEND); cogl_enable (CGL_ENABLE_TEXTURE_2D|CGL_ENABLE_BLEND);
} }
col.alpha = clutter_actor_get_opacity (self); col.alpha = clutter_actor_get_abs_opacity (self);
cogl_color (&col); cogl_color (&col);
clutter_actor_get_coords (self, &x_1, &y_1, &x_2, &y_2); clutter_actor_get_coords (self, &x_1, &y_1, &x_2, &y_2);

View File

@ -396,6 +396,7 @@ clutter_entry_paint (ClutterActor *self)
gint width, actor_width; gint width, actor_width;
gint text_width; gint text_width;
gint cursor_x; gint cursor_x;
ClutterColor color = { 0, };
entry = CLUTTER_ENTRY(self); entry = CLUTTER_ENTRY(self);
priv = entry->priv; priv = entry->priv;
@ -465,10 +466,12 @@ clutter_entry_paint (ClutterActor *self)
priv->cursor_pos.x += priv->entry_padding; priv->cursor_pos.x += priv->entry_padding;
} }
priv->fgcol.alpha = clutter_actor_get_opacity (self); memcpy (&color, &priv->fgcol, sizeof (ClutterColor));
color.alpha = clutter_actor_get_abs_opacity (self);
pango_clutter_render_layout (priv->layout, pango_clutter_render_layout (priv->layout,
priv->text_x + priv->entry_padding, 0, priv->text_x + priv->entry_padding, 0,
&priv->fgcol, 0); &color, 0);
if (CLUTTER_ENTRY_GET_CLASS (entry)->paint_cursor) if (CLUTTER_ENTRY_GET_CLASS (entry)->paint_cursor)
CLUTTER_ENTRY_GET_CLASS (entry)->paint_cursor (entry); CLUTTER_ENTRY_GET_CLASS (entry)->paint_cursor (entry);

View File

@ -288,6 +288,7 @@ clutter_label_paint (ClutterActor *self)
{ {
ClutterLabel *label = CLUTTER_LABEL (self); ClutterLabel *label = CLUTTER_LABEL (self);
ClutterLabelPrivate *priv = label->priv; ClutterLabelPrivate *priv = label->priv;
ClutterColor color = { 0, };
if (priv->font_desc == NULL || priv->text == NULL) if (priv->font_desc == NULL || priv->text == NULL)
{ {
@ -302,9 +303,10 @@ clutter_label_paint (ClutterActor *self)
clutter_label_ensure_layout (label); clutter_label_ensure_layout (label);
priv->fgcol.alpha = clutter_actor_get_opacity (self); memcpy (&color, &priv->fgcol, sizeof (ClutterColor));
color.alpha = clutter_actor_get_abs_opacity (self);
pango_clutter_render_layout (priv->layout, 0, 0, &priv->fgcol, 0); pango_clutter_render_layout (priv->layout, 0, 0, &color, 0);
} }
static void static void

View File

@ -96,7 +96,7 @@ clutter_rectangle_paint (ClutterActor *self)
tmp_col.red = priv->border_color.red; tmp_col.red = priv->border_color.red;
tmp_col.green = priv->border_color.green; tmp_col.green = priv->border_color.green;
tmp_col.blue = priv->border_color.blue; tmp_col.blue = priv->border_color.blue;
tmp_col.alpha = clutter_actor_get_opacity (self); tmp_col.alpha = clutter_actor_get_abs_opacity (self);
cogl_color (&tmp_col); cogl_color (&tmp_col);
@ -134,7 +134,7 @@ clutter_rectangle_paint (ClutterActor *self)
tmp_col.red = priv->color.red; tmp_col.red = priv->color.red;
tmp_col.green = priv->color.green; tmp_col.green = priv->color.green;
tmp_col.blue = priv->color.blue; tmp_col.blue = priv->color.blue;
tmp_col.alpha = clutter_actor_get_opacity (self); tmp_col.alpha = clutter_actor_get_abs_opacity (self);
cogl_color (&tmp_col); cogl_color (&tmp_col);
@ -392,8 +392,7 @@ clutter_rectangle_set_color (ClutterRectangle *rectangle,
priv->color.blue = color->blue; priv->color.blue = color->blue;
priv->color.alpha = color->alpha; priv->color.alpha = color->alpha;
clutter_actor_set_opacity (CLUTTER_ACTOR (rectangle), clutter_actor_set_opacity (CLUTTER_ACTOR (rectangle), priv->color.alpha);
priv->color.alpha);
#if 0 #if 0
/* FIXME - appears to be causing border to always get drawn */ /* FIXME - appears to be causing border to always get drawn */
@ -403,7 +402,7 @@ clutter_rectangle_set_color (ClutterRectangle *rectangle,
priv->has_border = TRUE; priv->has_border = TRUE;
#endif #endif
if (CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (rectangle))) if (CLUTTER_ACTOR_IS_VISIBLE (rectangle))
clutter_actor_queue_redraw (CLUTTER_ACTOR (rectangle)); clutter_actor_queue_redraw (CLUTTER_ACTOR (rectangle));
g_object_notify (G_OBJECT (rectangle), "color"); g_object_notify (G_OBJECT (rectangle), "color");

View File

@ -847,8 +847,7 @@ clutter_texture_paint (ClutterActor *self)
break; break;
} }
col.alpha = clutter_actor_get_opacity (self); col.alpha = clutter_actor_get_abs_opacity (self);
cogl_color (&col); cogl_color (&col);
clutter_actor_get_coords (self, &x_1, &y_1, &x_2, &y_2); clutter_actor_get_coords (self, &x_1, &y_1, &x_2, &y_2);

View File

@ -3,7 +3,8 @@ noinst_PROGRAMS = test-textures test-events test-offscreen test-scale \
test-perspective test-rotate test-depth \ test-perspective test-rotate test-depth \
test-threads test-timeline test-score test-script \ test-threads test-timeline test-score test-script \
test-model test-grab test-effects test-fullscreen \ test-model test-grab test-effects test-fullscreen \
test-shader test-unproject test-viewport test-fbo test-shader test-unproject test-viewport test-fbo \
test-opacity
INCLUDES = -I$(top_srcdir)/ INCLUDES = -I$(top_srcdir)/
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
@ -33,6 +34,7 @@ test_model_SOURCES = test-model.c
test_effects_SOURCES = test-effects.c test_effects_SOURCES = test-effects.c
test_fullscreen_SOURCES = test-fullscreen.c test_fullscreen_SOURCES = test-fullscreen.c
test_viewport_SOURCES = test-viewport.c test_viewport_SOURCES = test-viewport.c
test_fbo_SOURCES = test-fbo.c test_fbo_SOURCES = test-fbo.c
test_opacity_SOURCES = test-opacity.c
EXTRA_DIST = redhand.png test-script.json EXTRA_DIST = redhand.png test-script.json

115
tests/test-opacity.c Normal file
View File

@ -0,0 +1,115 @@
#include <stdlib.h>
#include <stdio.h>
#include <glib.h>
#include <clutter/clutter.h>
int
main (int argc, char *argv[])
{
ClutterActor *stage, *group1, *group2, *label, *rect;
ClutterColor label_color = { 255, 0, 0, 128 };
ClutterColor rect_color = { 0, 0, 255, 255 };
ClutterColor color_check = { 0, };
clutter_init (&argc, &argv);
stage = clutter_stage_get_default ();
label = clutter_label_new_with_text ("Sans 18px", "Label, 50% opacity");
clutter_label_set_color (CLUTTER_LABEL (label), &label_color);
g_print ("label 50%%.get_color()/1\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
g_assert (color_check.alpha == label_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (stage), label, NULL);
clutter_actor_set_position (label, 10, 10);
g_print ("label 50%%.get_color()/2\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
g_assert (color_check.alpha == label_color.alpha);
g_print ("label 50%%.get_abs_opacity() = %d\n",
clutter_actor_get_abs_opacity (label));
g_assert (clutter_actor_get_abs_opacity (label) == 128);
clutter_actor_show (label);
group1 = clutter_group_new ();
clutter_actor_set_opacity (group1, 128);
clutter_container_add (CLUTTER_CONTAINER (stage), group1, NULL);
clutter_actor_set_position (group1, 10, 30);
clutter_actor_show (group1);
label = clutter_label_new_with_text ("Sans 18px", "Label+Group, 25% opacity");
clutter_label_set_color (CLUTTER_LABEL (label), &label_color);
g_print ("label 50%% + group 50%%.get_color()/1\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
g_assert (color_check.alpha == label_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (group1), label, NULL);
g_print ("label 50%% + group 50%%.get_color()/2\n");
clutter_label_get_color (CLUTTER_LABEL (label), &color_check);
g_assert (color_check.alpha == label_color.alpha);
g_print ("label 50%% + group 50%%.get_abs_opacity() = %d\n",
clutter_actor_get_abs_opacity (label));
g_assert (clutter_actor_get_abs_opacity (label) == 64);
clutter_actor_show (label);
group2 = clutter_group_new ();
clutter_container_add (CLUTTER_CONTAINER (group1), group2, NULL);
clutter_actor_set_position (group2, 10, 60);
clutter_actor_show (group2);
rect = clutter_rectangle_new_with_color (&rect_color);
clutter_actor_set_size (rect, 128, 128);
g_print ("rect 100%% + group 100%% + group 50%%.get_color()/1\n");
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
g_assert (color_check.alpha == rect_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (group2), rect, NULL);
g_print ("rect 100%% + group 100%% + group 50%%.get_color()/2\n");
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
g_assert (color_check.alpha == rect_color.alpha);
g_print ("rect 100%%.get_abs_opacity() = %d\n",
clutter_actor_get_abs_opacity (rect));
g_assert (clutter_actor_get_abs_opacity (rect) == 128);
clutter_actor_show (rect);
rect = clutter_rectangle_new_with_color (&rect_color);
clutter_actor_set_size (rect, 128, 128);
clutter_actor_set_position (rect, 150, 90);
g_print ("rect 100%%.get_color()/1\n");
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
g_assert (color_check.alpha == rect_color.alpha);
clutter_container_add (CLUTTER_CONTAINER (stage), rect, NULL);
g_print ("rect 100%%.get_color()/2\n");
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &color_check);
g_assert (color_check.alpha == rect_color.alpha);
g_print ("rect 100%%.get_abs_opacity() = %d\n",
clutter_actor_get_abs_opacity (rect));
g_assert (clutter_actor_get_abs_opacity (rect) == 255);
clutter_actor_show (rect);
clutter_actor_show_all (stage);
clutter_main ();
return EXIT_SUCCESS;
}