]> git.cworth.org Git - wordgame/blob - demo-item.c
Make rack-fancy select and display a rack of 7 random letters
[wordgame] / demo-item.c
1 /*
2  * GooCanvas Demo. Copyright (C) 2006 Damon Chaplin.
3  * Released under the GNU LGPL license. See COPYING for details.
4  *
5  * demo-item.c - a simple demo item.
6  */
7 #include <math.h>
8
9 #include "goocanvas.h"
10 #include "demo-item.h"
11
12 /* Use the GLib convenience macro to define the type. GooDemoItem is the
13    class struct, goo_demo_item is the function prefix, and our class is a
14    subclass of GOO_TYPE_CANVAS_ITEM_SIMPLE. */
15 G_DEFINE_TYPE (GooDemoItem, goo_demo_item, GOO_TYPE_CANVAS_ITEM_SIMPLE)
16
17 /* The standard object initialization function. */
18     static void
19 goo_demo_item_init (GooDemoItem *demo_item)
20 {
21     demo_item->x = 0.0;
22     demo_item->y = 0.0;
23     demo_item->width = 0.0;
24     demo_item->height = 0.0;
25 }
26
27 /* The convenience function to create new items. This should start with a 
28    parent argument and end with a variable list of object properties to fit
29    in with the standard canvas items. */
30 GooCanvasItem*
31 goo_demo_item_new (GooCanvasItem      *parent,
32                    gdouble             x,
33                    gdouble             y,
34                    gdouble             width,
35                    gdouble             height,
36                    char                letter,
37                    ...)
38 {
39     GooCanvasItem *item;
40     GooDemoItem *demo_item;
41     const char *first_property;
42     va_list var_args;
43
44     item = g_object_new (GOO_TYPE_DEMO_ITEM, NULL);
45
46     demo_item = (GooDemoItem*) item;
47     demo_item->x = x;
48     demo_item->y = y;
49     demo_item->width = width;
50     demo_item->height = height;
51     demo_item->letter = letter;
52
53     va_start (var_args, letter);
54     first_property = va_arg (var_args, char*);
55     if (first_property)
56         g_object_set_valist ((GObject*) item, first_property, var_args);
57     va_end (var_args);
58
59     if (parent)
60     {
61         goo_canvas_item_add_child (parent, item, -1);
62         g_object_unref (item);
63     }
64
65     return item;
66 }
67
68 /* The update method. This is called when the canvas is initially shown and
69    also whenever the object is updated and needs to change its size and/or
70    shape. It should calculate its new bounds, storing them in simple->bounds,
71    and it should convert these to device coordinates. */
72 static void
73 goo_demo_item_update  (GooCanvasItemSimple *simple,
74                        cairo_t             *cr)
75 {
76     GooDemoItem *demo_item = (GooDemoItem*) simple;
77
78     /* Compute the new bounds. */
79     simple->bounds.x1 = demo_item->x;
80     simple->bounds.y1 = demo_item->y;
81     simple->bounds.x2 = demo_item->x + demo_item->width;
82     simple->bounds.y2 = demo_item->y + demo_item->height;
83
84     /* Convert to device coordinates. */
85     goo_canvas_item_simple_user_bounds_to_device (simple, cr, &simple->bounds);
86 }
87
88 /* The paint method. This should draw the item on the given cairo_t, using
89    the item's own coordinate space. */
90 static void
91 goo_demo_item_paint (GooCanvasItemSimple *simple,
92                      cairo_t             *cr,
93                      GooCanvasBounds     *bounds)
94 {
95     GooDemoItem *item = (GooDemoItem*) simple;
96     cairo_pattern_t *gradient;
97     cairo_text_extents_t extents;
98     int rad = (int) MIN (item->width / 2, item->height / 2);
99     int cx = item->x + item->width / 2;
100     int cy = item->y + item->height / 2;
101     double spot_angle = M_PI / 4.0;
102     double spot_rad = rad / 2.0;
103     char string[2];
104
105     cairo_save (cr);
106
107     gradient = cairo_pattern_create_radial (cx - spot_rad * cos (spot_angle),
108                                             cy - spot_rad * sin (spot_angle),
109                                             0.0,
110                                             cx - spot_rad * cos (spot_angle),
111                                             cy - spot_rad * sin (spot_angle),
112                                             rad + spot_rad);
113     cairo_pattern_add_color_stop_rgb (gradient, 0.0, 1.0, 1.0, 1.0);
114     cairo_pattern_add_color_stop_rgb (gradient, 1.0, 0.33, 0.33, 0.33);
115
116     cairo_set_source (cr, gradient);
117
118     cairo_arc (cr,
119                cx, cy,
120                rad, 0, 2 * M_PI);
121
122     cairo_fill (cr);
123
124     cairo_select_font_face (cr, "mono",
125                             CAIRO_FONT_SLANT_NORMAL,
126                             CAIRO_FONT_WEIGHT_BOLD);
127     cairo_set_font_size (cr, 1.8 * rad);
128
129     string[0] = item->letter;
130     string[1] = '\0';
131     cairo_text_extents (cr, string, &extents);
132     cairo_move_to (cr,
133                    cx - extents.width / 2 - extents.x_bearing,
134                    cy - extents.height / 2 - extents.y_bearing);
135
136     cairo_set_source_rgb (cr, 0.2, 0.3, 0.8);
137     cairo_show_text (cr, string);
138                    
139
140     cairo_restore (cr);
141 }
142
143 /* Hit detection. This should check if the given coordinate (in the item's
144    coordinate space) is within the item. If it is it should return the item,
145    otherwise it should return NULL. */
146 static GooCanvasItem*
147 goo_demo_item_get_item_at (GooCanvasItemSimple *simple,
148                            gdouble              x,
149                            gdouble              y,
150                            cairo_t             *cr,
151                            gboolean             is_pointer_event)
152 {
153     GooDemoItem *demo_item = (GooDemoItem*) simple;
154
155     if (x < demo_item->x || (x > demo_item->x + demo_item->width)
156         || y < demo_item->y || (y > demo_item->y + demo_item->height))
157         return NULL;
158
159     return (GooCanvasItem*) simple;
160 }
161
162 /* The class initialization function. Here we set the class' update(), paint()
163    and get_item_at() methods. */
164 static void
165 goo_demo_item_class_init (GooDemoItemClass *klass)
166 {
167     GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;
168
169     simple_class->update        = goo_demo_item_update;
170     simple_class->paint         = goo_demo_item_paint;
171     simple_class->get_item_at   = goo_demo_item_get_item_at;
172 }