Port BigBox to Clutter-0.9

- include only <clutter/clutter.h>
- cogl_rectangle() takes x1/y1/x2/y2 instead of x/y/width/height
- cogl_color() renamed to cogl_set_source_color4ub()
- use explicit CoglMaterial in BigRectangle to combine a texture
  and a color.
- Remove defensive calls to cogl_enable(0) - cogl_enable() no
  longer exists (enable flags are part of the material)
- Use ClutterCairoTexture actor (from Clutter) rather than ClutterCairo
This commit is contained in:
Owen W. Taylor 2009-02-19 14:33:41 -05:00
parent 902c29aa0c
commit f90523288d
3 changed files with 124 additions and 94 deletions

View File

@ -22,9 +22,7 @@
#include <glib.h> #include <glib.h>
#include <clutter/clutter-units.h> #include <clutter/clutter.h>
#include <clutter/clutter-actor.h>
#include <clutter/clutter-container.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <gdk-pixbuf/gdk-pixbuf.h> #include <gdk-pixbuf/gdk-pixbuf.h>
@ -2196,7 +2194,6 @@ big_box_paint (ClutterActor *actor)
ClutterColor color; ClutterColor color;
guint8 actor_opacity; guint8 actor_opacity;
ClutterGeometry allocation; ClutterGeometry allocation;
ClutterGeometry bg_rect;
int border_top, border_bottom, border_left, border_right; int border_top, border_bottom, border_left, border_right;
int padding_top, padding_bottom, padding_left, padding_right; int padding_top, padding_bottom, padding_left, padding_right;
@ -2217,8 +2214,6 @@ big_box_paint (ClutterActor *actor)
*/ */
clutter_actor_get_allocation_geometry (actor, &allocation); clutter_actor_get_allocation_geometry (actor, &allocation);
cogl_enable(0); /* defeat cogl GL cache in case GL used directly */
cogl_push_matrix (); cogl_push_matrix ();
/* Background */ /* Background */
@ -2226,11 +2221,6 @@ big_box_paint (ClutterActor *actor)
color = self->priv->background_color; color = self->priv->background_color;
color.alpha = (color.alpha * actor_opacity) / 0xff; color.alpha = (color.alpha * actor_opacity) / 0xff;
bg_rect.x = border_left;
bg_rect.y = border_top;
bg_rect.width = allocation.width - border_left - border_right;
bg_rect.height = allocation.height - border_top - border_bottom;
/* Border */ /* Border */
if (self->priv->draw_rounded_corner) if (self->priv->draw_rounded_corner)
@ -2245,8 +2235,11 @@ big_box_paint (ClutterActor *actor)
{ {
if (color.alpha != 0) if (color.alpha != 0)
{ {
cogl_color (&color); cogl_set_source_color4ub (color.red, color.green, color.blue, color.alpha);
cogl_rectangle (bg_rect.x, bg_rect.y, bg_rect.width, bg_rect.height);
cogl_rectangle (border_left, border_top,
allocation.width - border_left,
allocation.height - border_bottom);
} }
color = self->priv->border_color; color = self->priv->border_color;
@ -2254,7 +2247,7 @@ big_box_paint (ClutterActor *actor)
if (color.alpha != 0) if (color.alpha != 0)
{ {
cogl_color (&color); cogl_set_source_color4ub (color.red, color.green, color.blue, color.alpha);
/* top */ /* top */
cogl_rectangle (0, 0, cogl_rectangle (0, 0,
@ -2264,27 +2257,24 @@ big_box_paint (ClutterActor *actor)
/* left */ /* left */
cogl_rectangle (0, border_top, cogl_rectangle (0, border_top,
border_left, border_left,
allocation.height - border_top - border_bottom); allocation.height - border_top);
/* right */ /* right */
cogl_rectangle (allocation.width - border_right, cogl_rectangle (allocation.width - border_right,
border_top, border_top,
border_right, allocation.width,
allocation.height - border_top - border_bottom); allocation.height - border_top);
/* bottom */ /* bottom */
cogl_rectangle (0, allocation.height - border_bottom, cogl_rectangle (0, allocation.height - border_bottom,
allocation.width, allocation.width,
border_bottom); allocation.height);
} }
} }
cogl_enable(0); /* defeat cogl GL cache in case GL used directly */
if (self->priv->background_texture && if (self->priv->background_texture &&
CLUTTER_ACTOR_IS_VISIBLE(self->priv->background_texture)) { CLUTTER_ACTOR_IS_VISIBLE(self->priv->background_texture)) {
clutter_actor_paint (CLUTTER_ACTOR (self->priv->background_texture)); clutter_actor_paint (CLUTTER_ACTOR (self->priv->background_texture));
cogl_enable(0); /* defeat cogl GL cache in case GL used directly */
} }
/* Children */ /* Children */
@ -2299,7 +2289,6 @@ big_box_paint (ClutterActor *actor)
if (BOX_CHILD_IS_VISIBLE (child)) { if (BOX_CHILD_IS_VISIBLE (child)) {
clutter_actor_paint (child->actor); clutter_actor_paint (child->actor);
cogl_enable(0); /* defeat cogl GL cache in case GL used directly */
} }
} }

View File

@ -45,6 +45,9 @@ struct BigRectangle {
ClutterRectangle parent_instance; ClutterRectangle parent_instance;
ClutterUnit radius; ClutterUnit radius;
Corner *corner; Corner *corner;
CoglHandle corner_material;
CoglHandle border_material;
CoglHandle background_material;
gboolean corners_dirty; gboolean corners_dirty;
}; };
@ -299,6 +302,14 @@ big_rectangle_update_corners(BigRectangle *rectangle)
rectangle->corner = corner; rectangle->corner = corner;
if (corner) {
if (!rectangle->corner_material)
rectangle->corner_material = cogl_material_new();
cogl_material_set_layer (rectangle->corner_material, 0,
rectangle->corner->texture);
}
rectangle->corners_dirty = FALSE; rectangle->corners_dirty = FALSE;
} }
@ -308,14 +319,14 @@ big_rectangle_paint(ClutterActor *actor)
BigRectangle *rectangle; BigRectangle *rectangle;
ClutterColor *color; ClutterColor *color;
ClutterColor *border_color; ClutterColor *border_color;
guint8 actor_opacity;
CoglColor tmp_color;
guint border_width; guint border_width;
ClutterActorBox box; ClutterActorBox box;
ClutterFixed radiusx; float radius;
ClutterFixed widthx; float width;
ClutterFixed heightx; float height;
ClutterFixed border_widthx; float max;
ClutterFixed max;
ClutterColor tmp_col;
rectangle = BIG_RECTANGLE(actor); rectangle = BIG_RECTANGLE(actor);
@ -335,97 +346,113 @@ big_rectangle_paint(ClutterActor *actor)
"color", &color, "color", &color,
NULL); NULL);
actor_opacity = clutter_actor_get_paint_opacity (actor);
clutter_actor_get_allocation_box(actor, &box); clutter_actor_get_allocation_box(actor, &box);
/* translation was already done */ /* translation was already done */
box.x2 -= box.x1; box.x2 -= box.x1;
box.y2 -= box.y1; box.y2 -= box.y1;
widthx = CLUTTER_UNITS_TO_FIXED(box.x2); width = box.x2;
heightx = CLUTTER_UNITS_TO_FIXED(box.y2); height = box.y2;
radiusx = CLUTTER_UNITS_TO_FIXED(rectangle->radius); radius = rectangle->radius;
border_widthx = CLUTTER_INT_TO_FIXED(border_width); max = MAX(border_width, radius);
max = MAX(border_widthx, radiusx);
if (radiusx != 0) { if (radius != 0) {
tmp_col.red = 0xFF; cogl_color_set_from_4ub(&tmp_color,
tmp_col.blue = 0xFF; 0xff, 0xff, 0xff, actor_opacity);
tmp_col.green = 0xFF; cogl_material_set_color(rectangle->corner_material, &tmp_color);
tmp_col.alpha = clutter_actor_get_paint_opacity(actor); cogl_set_source(rectangle->corner_material);
cogl_color(&tmp_col);
/* NW */ /* NW */
cogl_texture_rectangle(rectangle->corner->texture, cogl_rectangle_with_texture_coords(0, 0,
0, 0, max, max,
max, max, 0, 0,
0, 0, 0.5, 0.5);
CFX_HALF, CFX_HALF);
/* NE */ /* NE */
cogl_texture_rectangle(rectangle->corner->texture, cogl_rectangle_with_texture_coords(width - max, 0,
widthx - max, 0, width, max,
widthx, max, 0.5, 0,
CFX_HALF, 0, 1.0, 0.5);
CFX_ONE, CFX_HALF);
/* SW */ /* SW */
cogl_texture_rectangle(rectangle->corner->texture, cogl_rectangle_with_texture_coords(0, height - max,
0, heightx - max, max, height,
max, heightx, 0, 0.5,
0, CFX_HALF, 0.5, 1.0);
CFX_HALF, CFX_ONE);
/* SE */ /* SE */
cogl_texture_rectangle(rectangle->corner->texture, cogl_rectangle_with_texture_coords(width - max, height - max,
widthx - max, heightx - max, width, height,
widthx, heightx, 0.5, 0.5,
CFX_HALF, CFX_HALF, 1.0, 1.0);
CFX_ONE, CFX_ONE);
} }
if (border_width != 0) { if (border_width != 0) {
tmp_col = *border_color; if (!rectangle->border_material)
rectangle->border_material = cogl_material_new ();
tmp_col.alpha = clutter_actor_get_paint_opacity(actor) * tmp_col.alpha / 255; cogl_color_set_from_4ub(&tmp_color,
border_color->red,
cogl_color(&tmp_col); border_color->green,
border_color->blue,
actor_opacity * border_color->alpha / 255);
cogl_material_set_color(rectangle->border_material, &tmp_color);
cogl_set_source(rectangle->border_material);
/* NORTH */ /* NORTH */
cogl_rectanglex(max, 0, cogl_rectangle(max, 0,
widthx - 2 * max, border_widthx); width - max, border_width);
/* EAST */ /* EAST */
cogl_rectanglex(widthx - border_widthx, max, cogl_rectangle(width - border_width, max,
border_widthx, heightx - 2 * max); width, height - max);
/* SOUTH */ /* SOUTH */
cogl_rectanglex(max, heightx - border_widthx, cogl_rectangle(max, height - border_width,
widthx - 2 * max, border_widthx); width - max, height);
/* WEST */ /* WEST */
cogl_rectanglex(0, max, cogl_rectangle(0, max,
border_widthx, heightx - 2 * max); border_width, height - max);
} }
tmp_col = *color; if (!rectangle->background_material)
tmp_col.alpha = clutter_actor_get_paint_opacity(actor) * tmp_col.alpha / 255; rectangle->background_material = cogl_material_new ();
cogl_color(&tmp_col); cogl_color_set_from_4ub(&tmp_color,
color->red,
color->green,
color->blue,
actor_opacity * color->alpha / 255);
cogl_material_set_color(rectangle->background_material, &tmp_color);
cogl_set_source(rectangle->background_material);
if (radiusx > border_widthx) { if (radius > border_width) {
cogl_rectanglex(radiusx, border_widthx, /* Once we've drawn the borders and corners, if the corners are bigger
widthx - radiusx - radiusx, radiusx - border_widthx); * the the border width, the remaining area is shaped like
cogl_rectanglex(radiusx, heightx - radiusx, *
widthx - 2 * radiusx, radiusx - border_widthx); * ########
* ##########
* ##########
* ########
*
* We draw it in 3 pieces - first the top and bottom, then the main
* rectangle
*/
cogl_rectangle(radius, border_width,
width - radius, radius);
cogl_rectangle(radius, height - radius,
width - radius, height - border_width);
} }
cogl_rectanglex(border_widthx, MAX(radiusx, border_widthx), cogl_rectangle(border_width, max,
widthx - 2 * border_widthx, heightx - 2 * MAX(radiusx, border_widthx)); width - border_width, height - max);
clutter_color_free(border_color); clutter_color_free(border_color);
clutter_color_free(color); clutter_color_free(color);
@ -497,12 +524,28 @@ big_rectangle_dispose(GObject *object)
rectangle = BIG_RECTANGLE(object); rectangle = BIG_RECTANGLE(object);
rectangle->radius = 0; if (rectangle->corner) {
big_rectangle_update_corners(rectangle); corner_unref(rectangle->corner);
rectangle->corner = NULL;
}
if (rectangle->corner_material) {
cogl_material_unref (rectangle->corner_material);
rectangle->corner_material = NULL;
}
if (rectangle->background_material) {
cogl_material_unref (rectangle->background_material);
rectangle->background_material = NULL;
}
if (rectangle->border_material) {
cogl_material_unref (rectangle->border_material);
rectangle->border_material = NULL;
}
if (G_OBJECT_CLASS(big_rectangle_parent_class)->dispose) if (G_OBJECT_CLASS(big_rectangle_parent_class)->dispose)
G_OBJECT_CLASS(big_rectangle_parent_class)->dispose(object); G_OBJECT_CLASS(big_rectangle_parent_class)->dispose(object);
} }

View File

@ -22,9 +22,7 @@
#include <glib.h> #include <glib.h>
#include <clutter/clutter-units.h> #include <clutter/clutter.h>
#include <clutter/clutter-actor.h>
#include <clutter-cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h> #include <gdk-pixbuf/gdk-pixbuf.h>
@ -41,7 +39,7 @@ typedef enum {
} BigThemeImageType; } BigThemeImageType;
struct BigThemeImage { struct BigThemeImage {
ClutterCairo parent_instance; ClutterCairoTexture parent_instance;
guint border_top; guint border_top;
guint border_bottom; guint border_bottom;
@ -60,10 +58,10 @@ struct BigThemeImage {
}; };
struct BigThemeImageClass { struct BigThemeImageClass {
ClutterCairoClass parent_class; ClutterCairoTextureClass parent_class;
}; };
G_DEFINE_TYPE(BigThemeImage, big_theme_image, CLUTTER_TYPE_CAIRO) G_DEFINE_TYPE(BigThemeImage, big_theme_image, CLUTTER_TYPE_CAIRO_TEXTURE)
enum enum
{ {
@ -144,7 +142,7 @@ big_theme_image_render(BigThemeImage *image)
dest_width = geometry.width; dest_width = geometry.width;
dest_height = geometry.height; dest_height = geometry.height;
cr = clutter_cairo_create(CLUTTER_CAIRO(image)); cr = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(image));
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
switch (j) { switch (j) {
@ -301,7 +299,7 @@ big_theme_image_allocate(ClutterActor *actor,
if (width != old_width || height != old_height) { if (width != old_width || height != old_height) {
clutter_cairo_surface_resize(CLUTTER_CAIRO(actor), width, height); clutter_cairo_texture_set_surface_size(CLUTTER_CAIRO_TEXTURE(actor), width, height);
big_theme_image_queue_render(image); big_theme_image_queue_render(image);
} }