]> git.cworth.org Git - wordgame/blob - demo-item.c
Add key press handling (letter guessing and backspace)
[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->size = 0.0;
22 }
23
24 void
25 goo_demo_item_move_to (GooCanvasItem    *item,
26                        gdouble           x,
27                        gdouble           y)
28 {
29     cairo_matrix_t matrix;
30
31     cairo_matrix_init_translate (&matrix, x, y);
32     goo_canvas_item_set_transform (item, &matrix);
33 }
34
35 void
36 goo_demo_item_glide_to (GooCanvasItem   *item,
37                         gdouble          x,
38                         gdouble          y)
39 {
40     goo_canvas_item_animate (item, x, y,
41                              1.0, 0,
42                              500, 40,
43                              GOO_CANVAS_ANIMATE_FREEZE);
44 }
45
46 /* The convenience function to create new items. This should start with a 
47    parent argument and end with a variable list of object properties to fit
48    in with the standard canvas items. */
49 GooCanvasItem*
50 goo_demo_item_new (GooCanvasItem      *parent,
51                    gdouble             x,
52                    gdouble             y,
53                    gdouble             size,
54                    char                letter,
55                    ...)
56 {
57     GooCanvasItem *item;
58     GooDemoItem *demo_item;
59     const char *first_property;
60     va_list var_args;
61
62     item = g_object_new (GOO_TYPE_DEMO_ITEM, NULL);
63
64     demo_item = (GooDemoItem*) item;
65     demo_item->size = size;
66     demo_item->letter = letter;
67
68     va_start (var_args, letter);
69     first_property = va_arg (var_args, char*);
70     if (first_property)
71         g_object_set_valist ((GObject*) item, first_property, var_args);
72     va_end (var_args);
73
74     if (parent)
75     {
76         goo_canvas_item_add_child (parent, item, -1);
77         g_object_unref (item);
78     }
79
80     goo_demo_item_move_to (item, x, y);
81
82     return item;
83 }
84
85 /* The update method. This is called when the canvas is initially shown and
86    also whenever the object is updated and needs to change its size and/or
87    shape. It should calculate its new bounds, storing them in simple->bounds,
88    and it should convert these to device coordinates. */
89 static void
90 goo_demo_item_update  (GooCanvasItemSimple *simple,
91                        cairo_t             *cr)
92 {
93     GooDemoItem *demo_item = (GooDemoItem*) simple;
94
95     /* Compute the new bounds. */
96     simple->bounds.x1 = 0;
97     simple->bounds.y1 = 0;
98     simple->bounds.x2 = demo_item->size;
99     simple->bounds.y2 = demo_item->size;
100
101     /* Convert to device coordinates. */
102     goo_canvas_item_simple_user_bounds_to_device (simple, cr, &simple->bounds);
103 }
104
105 /* The paint method. This should draw the item on the given cairo_t, using
106    the item's own coordinate space. */
107 static void
108 goo_demo_item_paint (GooCanvasItemSimple *simple,
109                      cairo_t             *cr,
110                      GooCanvasBounds     *bounds)
111 {
112     GooDemoItem *item = (GooDemoItem*) simple;
113     cairo_pattern_t *gradient;
114     cairo_text_extents_t extents;
115     int rad = (int) (item->size / 2);
116     int cx = item->size / 2;
117     int cy = cx;
118     int tx, ty;
119     double spot_angle = M_PI / 4.0;
120     double spot_rad = rad / 2.0;
121     char string[2];
122
123     cairo_save (cr);
124
125     gradient = cairo_pattern_create_radial (cx - spot_rad * cos (spot_angle),
126                                             cy - spot_rad * sin (spot_angle),
127                                             0.0,
128                                             cx - spot_rad * cos (spot_angle),
129                                             cy - spot_rad * sin (spot_angle),
130                                             rad + spot_rad);
131     cairo_pattern_add_color_stop_rgb (gradient, 0.0, 1.0, 1.0, 1.0);
132     cairo_pattern_add_color_stop_rgb (gradient, 1.0, 0.33, 0.33, 0.33);
133
134     cairo_set_source (cr, gradient);
135
136     cairo_arc (cr,
137                cx, cy,
138                rad, 0, 2 * M_PI);
139
140     cairo_fill (cr);
141
142     cairo_select_font_face (cr, "mono",
143                             CAIRO_FONT_SLANT_NORMAL,
144                             CAIRO_FONT_WEIGHT_BOLD);
145     cairo_set_font_size (cr, 1.8 * rad);
146
147     string[0] = item->letter;
148     string[1] = '\0';
149     cairo_text_extents (cr, string, &extents);
150     tx = cx - extents.width / 2 - extents.x_bearing;
151     ty = cy - extents.height / 2 - extents.y_bearing;
152
153     cairo_set_source_rgb (cr, 0.7, 0.7, 0.7);
154     cairo_move_to (cr, tx + 1, ty + 1);
155     cairo_show_text (cr, string);
156                 
157     cairo_set_source_rgb (cr, 0.33, 0.33, 0.33);
158     cairo_move_to (cr, tx - 1, ty - 1);
159     cairo_show_text (cr, string);
160
161     cairo_set_source_rgb (cr, 0.2, 0.3, 0.8);
162     cairo_move_to (cr, tx, ty);
163     cairo_show_text (cr, string);
164
165     cairo_restore (cr);
166 }
167
168 /* Hit detection. This should check if the given coordinate (in the item's
169    coordinate space) is within the item. If it is it should return the item,
170    otherwise it should return NULL. */
171 static GooCanvasItem*
172 goo_demo_item_get_item_at (GooCanvasItemSimple *simple,
173                            gdouble              x,
174                            gdouble              y,
175                            cairo_t             *cr,
176                            gboolean             is_pointer_event)
177 {
178     GooDemoItem *demo_item = (GooDemoItem*) simple;
179
180     if (x < 0 || (x > demo_item->size)
181         || y < 0 || (y > demo_item->size))
182         return NULL;
183
184     return (GooCanvasItem*) simple;
185 }
186
187 /* The class initialization function. Here we set the class' update(), paint()
188    and get_item_at() methods. */
189 static void
190 goo_demo_item_class_init (GooDemoItemClass *klass)
191 {
192     GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;
193
194     simple_class->update        = goo_demo_item_update;
195     simple_class->paint         = goo_demo_item_paint;
196     simple_class->get_item_at   = goo_demo_item_get_item_at;
197 }