Fixed some valgrind errors from using uninitialized variables in
[ardour.git] / gtk2_ardour / canvas-ruler.c
1 #include <stdio.h>
2 #include <math.h>
3 #include <libgnomecanvas/libgnomecanvas.h>
4
5 #include "canvas-ruler.h"
6 #include "rgb_macros.h"
7
8 enum {
9         PROP_0,
10         PROP_X1,
11         PROP_Y1,
12         PROP_X2,
13         PROP_Y2,
14         PROP_FRAMES_PER_UNIT,
15         PROP_FILL_COLOR,
16         PROP_TICK_COLOR
17
18 };
19
20 static void gnome_canvas_ruler_class_init (GnomeCanvasRulerClass *class);
21 static void gnome_canvas_ruler_init       (GnomeCanvasRuler      *ruler);
22 static void gnome_canvas_ruler_set_arg    (GObject              *object,
23                                            guint                   prop_id
24                                            const GValue   *value,
25                                            GParamSpec     *pspec);
26 static void gnome_canvas_ruler_get_arg    (GObject              *object,
27                                            guint                   prop_id
28                                            GValue   *value,
29                                            GParamSpec     *pspec);
30 static void   gnome_canvas_ruler_update      (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags);
31 static void   gnome_canvas_ruler_bounds      (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2);
32 static double gnome_canvas_ruler_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item);
33 static void   gnome_canvas_ruler_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf);
34 static void   gnome_canvas_ruler_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int w, int h);
35
36 static GnomeCanvasItemClass *parent_class;
37
38
39 GtkType
40 gnome_canvas_ruler_get_type (void)
41 {
42         static GtkType ruler_type = 0;
43
44         if (!ruler_type) {
45                 GtkTypeInfo ruler_info = {
46                         "GnomeCanvasRuler",
47                         sizeof (GnomeCanvasRuler),
48                         sizeof (GnomeCanvasRulerClass),
49                         (GtkClassInitFunc) gnome_canvas_ruler_class_init,
50                         (GtkObjectInitFunc) gnome_canvas_ruler_init,
51                         NULL, /* reserved_1 */
52                         NULL, /* reserved_2 */
53                         (GtkClassInitFunc) NULL
54                 };
55
56                 ruler_type = gtk_type_unique (gnome_canvas_item_get_type (), &ruler_info);
57         }
58
59         return ruler_type;
60 }
61
62 static void
63 gnome_canvas_ruler_class_init (GnomeCanvasRulerClass *class)
64 {
65         GtkObjectClass *object_class;
66         GnomeCanvasItemClass *item_class;
67
68         object_class = G_OBJECT_CLASS  (class);
69         item_class = (GnomeCanvasItemClass *) class;
70
71         parent_class = gtk_type_class (gnome_canvas_item_get_type ());
72
73         object_class->set_property = gnome_canvas_ruler_set_property;
74         object_class->get_property = gnome_canvas_ruler_get_property;
75
76         g_object_class_install_property (object_class,
77                                          PROP_X1,
78                                          g_param_spec_double ("x1",
79                                                               _("x1"),
80                                                               _("x coordinate of upper left corner of rect"),
81                                                               -G_MAXDOUBLE,
82                                                               G_MAXDOUBLE,
83                                                               0.0,
84                                                               G_PARAM_READWRITE));  
85         
86         g_object_class_install_property (object_class,
87                                          PROP_Y1,
88                                          g_param_spec_double ("y1",
89                                                               _("y1"),
90                                                               _("y coordinate of upper left corner of rect "),
91                                                               -G_MAXDOUBLE,
92                                                               G_MAXDOUBLE,
93                                                               0.0,
94                                                               G_PARAM_READWRITE));  
95         
96         
97         g_object_class_install_property (object_class,
98                                          PROP_X2,
99                                          g_param_spec_double ("x2",
100                                                               _("x2"),
101                                                               _("x coordinate of lower right corner of rect"),
102                                                               -G_MAXDOUBLE,
103                                                               G_MAXDOUBLE,
104                                                               0.0,
105                                                               G_PARAM_READWRITE));  
106         
107         g_object_class_install_property (object_class,
108                                          PROP_Y2,
109                                          g_param_spec_double ("y2",
110                                                               _("y2"),
111                                                               _("y coordinate of lower right corner of rect "),
112                                                               -G_MAXDOUBLE,
113                                                               G_MAXDOUBLE,
114                                                               0.0,
115                                                               G_PARAM_READWRITE));  
116         
117         
118         g_object_class_install_property (object_class,
119                                          PROP_FRAMES_PER_UNIT,
120                                          g_param_spec_long ("frames_per_unit",
121                                                             _("frames_per_unit"),
122                                                             _("frames_per_unit of ruler"),
123                                                             -G_MAXLONG,
124                                                             G_MAXLONG,
125                                                             0,
126                                                             G_PARAM_READWRITE)); 
127         
128         
129         g_object_class_install_property (object_class,
130                                          PROP_FILL_COLOR,
131                                          g_param_spec_uint ("fill_color",
132                                                             _("fill color"),
133                                                             _("color of fill"),
134                                                             0,
135                                                             G_MAXINT,
136                                                             0,
137                                                             G_PARAM_READWRITE)); 
138         
139         
140         g_object_class_install_property (object_class,
141                                          PROP_TICK_COLOR,
142                                          g_param_spec_uint ("tick_color",
143                                                             _("tick color"),
144                                                             _("color of tick"),
145                                                             0,
146                                                             G_MAXINT,
147                                                             0,
148                                                             G_PARAM_READWRITE)); 
149         item_class->update = gnome_canvas_ruler_update;
150         item_class->bounds = gnome_canvas_ruler_bounds;
151         item_class->point = gnome_canvas_ruler_point;
152         item_class->render = gnome_canvas_ruler_render;
153         item_class->draw = gnome_canvas_ruler_draw;
154 }
155
156 static void
157 gnome_canvas_ruler_init (GnomeCanvasRuler *ruler)
158 {
159         ruler->x1 = 0.0;
160         ruler->y1 = 0.0;
161         ruler->x2 = 0.0;
162         ruler->y2 = 0.0;
163         ruler->frames_per_unit = 1;
164         ruler->fill_color = 0;
165         ruler->tick_color = 0;
166 }
167
168 static void 
169 gnome_canvas_ruler_reset_bounds (GnomeCanvasItem *item)
170
171 {
172         double x1, x2, y1, y2;
173         ArtPoint i1, i2;
174         ArtPoint w1, w2;
175         int Ix1, Ix2, Iy1, Iy2;
176         double i2w[6];
177
178         gnome_canvas_ruler_bounds (item, &x1, &y1, &x2, &y2);
179
180         i1.x = x1;
181         i1.y = y1;
182         i2.x = x2;
183         i2.y = y2;
184
185         gnome_canvas_item_i2w_affine (item, i2w);
186         art_affine_point (&w1, &i1, i2w);
187         art_affine_point (&w2, &i2, i2w);
188
189         Ix1 = (int) rint(w1.x);
190         Ix2 = (int) rint(w2.x);
191         Iy1 = (int) rint(w1.y);
192         Iy2 = (int) rint(w2.y);
193
194         gnome_canvas_update_bbox (item, Ix1, Iy1, Ix2, Iy2);
195 }
196
197 /* 
198  * CANVAS CALLBACKS 
199  */
200
201 static void
202 gnome_canvas_ruler_set_property (GObject *object,
203 guint         prop_id,
204                                       const GValue *value,
205                                       GParamSpec   *pspec)
206 {
207         GnomeCanvasItem *item;
208         GnomeCanvasRuler *ruler;
209         int redraw;
210         int calc_bounds;
211
212         item = GNOME_CANVAS_ITEM (object);
213         ruler = GNOME_CANVAS_RULER (object);
214
215         redraw = FALSE;
216         calc_bounds = FALSE;
217
218         switch (prop_id) {
219         case PROP_X1:
220                 if (ruler->x1 != g_value_get_double (value)) {
221                         ruler->x1 = g_value_get_double (value);
222                         calc_bounds = TRUE;
223                 }
224                 break;
225
226         case PROP_Y1:
227                 if (ruler->y1 != g_value_get_double (value)) {
228                         ruler->y1 = g_value_get_double (value);
229                         calc_bounds = TRUE;
230                 }
231                 break;
232
233         case PROP_X2:
234                 if (ruler->x2 != g_value_get_double (value)) {
235                         ruler->x2 = g_value_get_double (value);
236                         calc_bounds = TRUE;
237                 }
238                 break;
239
240         case PROP_Y2:
241                 if (ruler->y2 != g_value_get_double (value)) {
242                         ruler->y2 = g_value_get_double (value);
243                         calc_bounds = TRUE;
244                 }
245                 break;
246
247         case PROP_FRAMES_PER_UNIT:
248                 if (ruler->frames_per_unit != g_value_get_long(value)) {
249                         ruler->frames_per_unit = g_value_get_long(value);
250                         redraw = TRUE;
251                 }
252                 break;
253
254         case PROP_FILL_COLOR:
255                 if (ruler->fill_color != g_value_get_uint(value)) {
256                         ruler->fill_color = g_value_get_uint(value);
257                         redraw = TRUE;
258                 }
259                 break;
260
261         case PROP_TICK_COLOR:
262                 if (ruler->tick_color != g_value_get_uint(value)) {
263                         ruler->tick_color = g_value_get_uint(value);
264                         redraw = TRUE;
265                 }
266                 break;
267
268         default:
269                 break;
270         }
271
272         if (calc_bounds) {
273                 gnome_canvas_ruler_reset_bounds (item);
274         }
275
276         if (redraw) {
277                 gnome_canvas_item_request_update (item);
278         }
279
280 }
281
282 static void
283 gnome_canvas_ruler_get_property (GObject *object,
284   guint         prop_id,
285                                       GValue       *value,
286                                       GParamSpec   *pspec)
287
288 {
289         GnomeCanvasRuler *ruler;
290
291         ruler = GNOME_CANVAS_RULER (object);
292
293         switch (prop_id) {
294         case PROP_X1:
295           g_value_set_double (value, ruler->x1);
296                 break;
297         case PROP_Y1:
298           g_value_set_double (value, ruler->y1);
299                 break;
300         case PROP_X2:
301           g_value_set_double (value, ruler->x2);
302                 break;
303         case PROP_Y2:
304           g_value_set_double (value, ruler->y2);
305                 break;
306         case PROP_FRAMES_PER_UNIT:
307           g_value_set_long (value, ruler->frames_per_unit);
308                 break;
309         case PROP_FILL_COLOR:
310           g_value_set_uint (value, ruler->fill_color);
311                 break;
312         case PROP_TICK_COLOR:
313           g_value_set_uint (value, ruler->tick_color);
314                 break;
315         default:
316                 arg->type = GTK_TYPE_INVALID;
317                 break;
318         }
319 }
320
321 static void
322 gnome_canvas_ruler_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
323 {
324         GnomeCanvasRuler *ruler;
325         double x;
326         double y;
327
328         ruler = GNOME_CANVAS_RULER (item);
329
330         if (parent_class->update)
331                 (* parent_class->update) (item, affine, clip_path, flags);
332
333         gnome_canvas_ruler_reset_bounds (item);
334
335         x = ruler->x1;
336         y = ruler->y1;
337
338         gnome_canvas_item_i2w (item, &x, &y);
339         gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x, y, &ruler->bbox_ulx, &ruler->bbox_uly);
340
341         x = ruler->x2;
342         y = ruler->y2;
343
344         gnome_canvas_item_i2w (item, &x, &y);
345         gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x, y, &ruler->bbox_lrx, &ruler->bbox_lry);
346
347         UINT_TO_RGB (ruler->tick_color, &ruler->tick_r, &ruler->tick_g, &ruler->tick_b);
348         UINT_TO_RGB (ruler->fill_color, &ruler->fill_r, &ruler->fill_g, &ruler->fill_b);
349 }
350
351 static void
352 gnome_canvas_ruler_render (GnomeCanvasItem *item,
353                               GnomeCanvasBuf *buf)
354 {
355         GnomeCanvasRuler *ruler;
356         int end, begin;
357
358         ruler = GNOME_CANVAS_RULER (item);
359
360         if (parent_class->render) {
361                 (*parent_class->render) (item, buf);
362         }
363
364         if (buf->is_bg) {
365                 gnome_canvas_buf_ensure_buf (buf);
366                 buf->is_bg = FALSE;
367         }
368
369         begin = MAX(ruler->bbox_ulx,buf->rect.x0);
370
371         if (ruler->bbox_lrx >= 0) {
372                 end = MIN(ruler->bbox_lrx,buf->rect.x1);
373         } else {
374                 end = buf->rect.x1;
375         }
376
377         if (begin == end) {
378                 return;
379         }
380
381         PAINT_BOX (buf, ruler->fill_r, ruler->fill_g, ruler->fill_b, 255, begin, ruler->bbox_uly, end, ruler->bbox_lry - 1);
382         PAINT_HORIZ (buf, ruler->tick_r, ruler->tick_g, ruler->tick_b, begin, end, ruler->bbox_lry - 1);
383 }
384
385 static void
386 gnome_canvas_ruler_draw (GnomeCanvasItem *item,
387                             GdkDrawable *drawable,
388                             int x, int y,
389                             int width, int height)
390 {
391         GnomeCanvasRuler *ruler;
392
393         ruler = GNOME_CANVAS_RULER (item);
394
395         if (parent_class->draw) {
396                 (* parent_class->draw) (item, drawable, x, y, width, height);
397         }
398
399         fprintf (stderr, "please don't use the CanvasRuler item in a non-aa Canvas\n");
400         abort ();
401 }
402
403 static void
404 gnome_canvas_ruler_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
405 {
406         GnomeCanvasRuler *ruler = GNOME_CANVAS_RULER (item);
407
408         *x1 = ruler->x1;
409         *y1 = ruler->y1;
410         *x2 = ruler->x2;
411         *y2 = ruler->y2;
412 }
413
414 static double
415 gnome_canvas_ruler_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item)
416 {
417         GnomeCanvasRuler *ruler;
418         double x1, y1, x2, y2;
419         double dx, dy;
420
421         ruler = GNOME_CANVAS_RULER (item);
422
423         *actual_item = item;
424
425         /* Find the bounds for the rectangle plus its outline width */
426
427         gnome_canvas_ruler_bounds (item, &x1, &y1, &x2, &y2);
428
429         /* Is point inside rectangle */
430         
431         if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
432                 return 0.0;
433         }
434
435         /* Point is outside rectangle */
436
437         if (x < x1)
438                 dx = x1 - x;
439         else if (x > x2)
440                 dx = x - x2;
441         else
442                 dx = 0.0;
443
444         if (y < y1)
445                 dy = y1 - y;
446         else if (y > y2)
447                 dy = y - y2;
448         else
449                 dy = 0.0;
450
451         return sqrt (dx * dx + dy * dy);
452 }