From: Carl Worth Date: Sat, 16 Dec 2006 23:52:37 +0000 (-0800) Subject: Abstract tile-specific code out of demo-item.c X-Git-Url: https://git.cworth.org/git?p=wordgame;a=commitdiff_plain;h=bcb2db8e93ce94b662e7118b92230c6eb749ee22 Abstract tile-specific code out of demo-item.c We now accomplish painting by simply passing in a callback function to do the painting. This will allow the single item class to be shared for all canvas items. --- diff --git a/demo-item.c b/demo-item.c index 0c8fc84..99c45fb 100644 --- a/demo-item.c +++ b/demo-item.c @@ -21,37 +21,14 @@ goo_demo_item_init (GooDemoItem *demo_item) demo_item->size = 0.0; } -void -goo_demo_item_move_to (GooCanvasItem *item, - gdouble x, - gdouble y) -{ - cairo_matrix_t matrix; - - cairo_matrix_init_translate (&matrix, x, y); - goo_canvas_item_set_transform (item, &matrix); -} - -void -goo_demo_item_glide_to (GooCanvasItem *item, - gdouble x, - gdouble y) -{ - goo_canvas_item_animate (item, x, y, - 1.0, 0, - 500, 40, - GOO_CANVAS_ANIMATE_FREEZE); -} - /* The convenience function to create new items. This should start with a parent argument and end with a variable list of object properties to fit in with the standard canvas items. */ GooCanvasItem* -goo_demo_item_new (GooCanvasItem *parent, - gdouble x, - gdouble y, - gdouble size, - char letter, +goo_demo_item_new (GooCanvasItem *parent, + gdouble size, + GooDemoItemPaintFunc paint, + void *closure, ...) { GooCanvasItem *item; @@ -63,9 +40,10 @@ goo_demo_item_new (GooCanvasItem *parent, demo_item = (GooDemoItem*) item; demo_item->size = size; - demo_item->letter = letter; + demo_item->paint = paint; + demo_item->closure = closure; - va_start (var_args, letter); + va_start (var_args, closure); first_property = va_arg (var_args, char*); if (first_property) g_object_set_valist ((GObject*) item, first_property, var_args); @@ -77,8 +55,6 @@ goo_demo_item_new (GooCanvasItem *parent, g_object_unref (item); } - goo_demo_item_move_to (item, x, y); - return item; } @@ -110,59 +86,8 @@ goo_demo_item_paint (GooCanvasItemSimple *simple, GooCanvasBounds *bounds) { GooDemoItem *item = (GooDemoItem*) simple; - cairo_pattern_t *gradient; - cairo_text_extents_t extents; - int rad = (int) (item->size / 2); - int cx = item->size / 2; - int cy = cx; - int tx, ty; - double spot_angle = M_PI / 4.0; - double spot_rad = rad / 2.0; - char string[2]; - - cairo_save (cr); - - gradient = cairo_pattern_create_radial (cx - spot_rad * cos (spot_angle), - cy - spot_rad * sin (spot_angle), - 0.0, - cx - spot_rad * cos (spot_angle), - cy - spot_rad * sin (spot_angle), - rad + spot_rad); - cairo_pattern_add_color_stop_rgb (gradient, 0.0, 1.0, 1.0, 1.0); - cairo_pattern_add_color_stop_rgb (gradient, 1.0, 0.33, 0.33, 0.33); - - cairo_set_source (cr, gradient); - - cairo_arc (cr, - cx, cy, - rad, 0, 2 * M_PI); - - cairo_fill (cr); - - cairo_select_font_face (cr, "mono", - CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size (cr, 1.8 * rad); - - string[0] = item->letter; - string[1] = '\0'; - cairo_text_extents (cr, string, &extents); - tx = cx - extents.width / 2 - extents.x_bearing; - ty = cy - extents.height / 2 - extents.y_bearing; - - cairo_set_source_rgb (cr, 0.7, 0.7, 0.7); - cairo_move_to (cr, tx + 1, ty + 1); - cairo_show_text (cr, string); - - cairo_set_source_rgb (cr, 0.33, 0.33, 0.33); - cairo_move_to (cr, tx - 1, ty - 1); - cairo_show_text (cr, string); - - cairo_set_source_rgb (cr, 0.2, 0.3, 0.8); - cairo_move_to (cr, tx, ty); - cairo_show_text (cr, string); - - cairo_restore (cr); + + item->paint (cr, item->closure); } /* Hit detection. This should check if the given coordinate (in the item's diff --git a/demo-item.h b/demo-item.h index 8cc4712..7918858 100644 --- a/demo-item.h +++ b/demo-item.h @@ -22,12 +22,14 @@ G_BEGIN_DECLS typedef struct _GooDemoItem GooDemoItem; typedef struct _GooDemoItemClass GooDemoItemClass; +typedef void (*GooDemoItemPaintFunc) (cairo_t *cr, void *); + struct _GooDemoItem { GooCanvasItemSimple parent_object; - double size; - char letter; + GooDemoItemPaintFunc paint; + void *closure; }; struct _GooDemoItemClass @@ -37,23 +39,12 @@ struct _GooDemoItemClass GType goo_demo_item_get_type (void) G_GNUC_CONST; -GooCanvasItem* goo_demo_item_new (GooCanvasItem *parent, - gdouble x, - gdouble y, - gdouble size, - char letter, +GooCanvasItem* goo_demo_item_new (GooCanvasItem *parent, + gdouble size, + GooDemoItemPaintFunc paint, + void *closure, ...); -void -goo_demo_item_move_to (GooCanvasItem *item, - gdouble x, - gdouble y); - -void -goo_demo_item_glide_to (GooCanvasItem *item, - gdouble x, - gdouble y); - G_END_DECLS #endif /* __GOO_DEMO_ITEM_H__ */ diff --git a/rack-fancy.c b/rack-fancy.c index 99d0aa0..abd2228 100644 --- a/rack-fancy.c +++ b/rack-fancy.c @@ -34,6 +34,7 @@ typedef struct _tile char letter; int rack_index; int x, y; + int size; GooCanvasItem *item; gboolean guessed; } tile_t; @@ -66,6 +67,86 @@ guess_tile_position (int i, int *x, int *y) *y -= (LETTER_SIZE + LETTER_PAD); } +static void +tile_paint (cairo_t *cr, void *closure) +{ + tile_t *tile = closure; + + cairo_pattern_t *gradient; + cairo_text_extents_t extents; + int rad = (int) (tile->size / 2); + int cx = tile->size / 2; + int cy = cx; + int tx, ty; + double spot_angle = M_PI / 4.0; + double spot_rad = rad / 2.0; + char string[2]; + + cairo_save (cr); + + gradient = cairo_pattern_create_radial (cx - spot_rad * cos (spot_angle), + cy - spot_rad * sin (spot_angle), + 0.0, + cx - spot_rad * cos (spot_angle), + cy - spot_rad * sin (spot_angle), + rad + spot_rad); + cairo_pattern_add_color_stop_rgb (gradient, 0.0, 1.0, 1.0, 1.0); + cairo_pattern_add_color_stop_rgb (gradient, 1.0, 0.33, 0.33, 0.33); + + cairo_set_source (cr, gradient); + + cairo_arc (cr, + cx, cy, + rad, 0, 2 * M_PI); + + cairo_fill (cr); + + cairo_select_font_face (cr, "mono", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size (cr, 1.8 * rad); + + string[0] = tile->letter; + string[1] = '\0'; + cairo_text_extents (cr, string, &extents); + tx = cx - extents.width / 2 - extents.x_bearing; + ty = cy - extents.height / 2 - extents.y_bearing; + + cairo_set_source_rgb (cr, 0.7, 0.7, 0.7); + cairo_move_to (cr, tx + 1, ty + 1); + cairo_show_text (cr, string); + + cairo_set_source_rgb (cr, 0.33, 0.33, 0.33); + cairo_move_to (cr, tx - 1, ty - 1); + cairo_show_text (cr, string); + + cairo_set_source_rgb (cr, 0.2, 0.3, 0.8); + cairo_move_to (cr, tx, ty); + cairo_show_text (cr, string); + + cairo_restore (cr); +} + +static void +tile_move_to (tile_t *tile, int x, int y) +{ + cairo_matrix_t matrix; + + cairo_matrix_init_translate (&matrix, x, y); + goo_canvas_item_set_transform (tile->item, &matrix); +} + +static void +tile_glide_to (tile_t *tile, int x, int y) +{ + goo_canvas_item_animate (tile->item, x, y, + 1.0, 0, + 500, 40, + GOO_CANVAS_ANIMATE_FREEZE); + tile->x = x; + tile->y = y; +} + static tile_t * tile_create (GooCanvasItem *parent, char letter, int rack_index) @@ -76,24 +157,19 @@ tile_create (GooCanvasItem *parent, tile->letter = tolower (letter); tile->rack_index = rack_index; rack_tile_position (rack_index, &tile->x, &tile->y); + tile->size = LETTER_SIZE; tile->item = goo_demo_item_new (parent, - tile->x, tile->y, - LETTER_SIZE, - toupper (letter), - NULL); + tile->size, + tile_paint, + tile); + + tile_move_to (tile, tile->x, tile->y); + tile->guessed = FALSE; return tile; } -static void -tile_glide_to (tile_t *tile, int x, int y) -{ - goo_demo_item_glide_to (tile->item, x, y); - tile->x = x; - tile->y = y; -} - static gboolean on_delete_event (GtkWidget *window, GdkEvent *event,