a few more header files fixes, plus cleanup from nick_m, and the start of Action...
[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         ARG_0,
10         ARG_X1,
11         ARG_Y1,
12         ARG_X2,
13         ARG_Y2,
14         ARG_FRAMES_PER_UNIT,
15         ARG_FILL_COLOR,
16         ARG_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    (GtkObject              *object,
23                                               GtkArg                 *arg,
24                                               guint                   arg_id);
25 static void gnome_canvas_ruler_get_arg    (GtkObject              *object,
26                                               GtkArg                 *arg,
27                                               guint                   arg_id);
28
29 static void   gnome_canvas_ruler_update      (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags);
30 static void   gnome_canvas_ruler_bounds      (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2);
31 static double gnome_canvas_ruler_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item);
32 static void   gnome_canvas_ruler_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf);
33 static void   gnome_canvas_ruler_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int w, int h);
34
35 static GnomeCanvasItemClass *parent_class;
36
37
38 GtkType
39 gnome_canvas_ruler_get_type (void)
40 {
41         static GtkType ruler_type = 0;
42
43         if (!ruler_type) {
44                 GtkTypeInfo ruler_info = {
45                         "GnomeCanvasRuler",
46                         sizeof (GnomeCanvasRuler),
47                         sizeof (GnomeCanvasRulerClass),
48                         (GtkClassInitFunc) gnome_canvas_ruler_class_init,
49                         (GtkObjectInitFunc) gnome_canvas_ruler_init,
50                         NULL, /* reserved_1 */
51                         NULL, /* reserved_2 */
52                         (GtkClassInitFunc) NULL
53                 };
54
55                 ruler_type = gtk_type_unique (gnome_canvas_item_get_type (), &ruler_info);
56         }
57
58         return ruler_type;
59 }
60
61 static void
62 gnome_canvas_ruler_class_init (GnomeCanvasRulerClass *class)
63 {
64         GtkObjectClass *object_class;
65         GnomeCanvasItemClass *item_class;
66
67         object_class = (GtkObjectClass *) class;
68         item_class = (GnomeCanvasItemClass *) class;
69
70         parent_class = gtk_type_class (gnome_canvas_item_get_type ());
71
72         gtk_object_add_arg_type ("GnomeCanvasRuler::x1", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_X1);
73         gtk_object_add_arg_type ("GnomeCanvasRuler::y1", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_Y1);
74         gtk_object_add_arg_type ("GnomeCanvasRuler::x2", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_X2);
75         gtk_object_add_arg_type ("GnomeCanvasRuler::y2", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_Y2);
76         gtk_object_add_arg_type ("GnomeCanvasRuler::frames_per_unit", GTK_TYPE_LONG, GTK_ARG_READWRITE, ARG_FRAMES_PER_UNIT);
77         gtk_object_add_arg_type ("GnomeCanvasRuler::fill_color", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_FILL_COLOR);
78         gtk_object_add_arg_type ("GnomeCanvasRuler::tick_color", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_TICK_COLOR);
79
80         object_class->set_arg = gnome_canvas_ruler_set_arg;
81         object_class->get_arg = gnome_canvas_ruler_get_arg;
82
83         item_class->update = gnome_canvas_ruler_update;
84         item_class->bounds = gnome_canvas_ruler_bounds;
85         item_class->point = gnome_canvas_ruler_point;
86         item_class->render = gnome_canvas_ruler_render;
87         item_class->draw = gnome_canvas_ruler_draw;
88 }
89
90 static void
91 gnome_canvas_ruler_init (GnomeCanvasRuler *ruler)
92 {
93         ruler->x1 = 0.0;
94         ruler->y1 = 0.0;
95         ruler->x2 = 0.0;
96         ruler->y2 = 0.0;
97         ruler->frames_per_unit = 1;
98         ruler->fill_color = 0;
99         ruler->tick_color = 0;
100
101         // GTK2FIX
102         //GNOME_CANVAS_ITEM(ruler)->object.flags |= GNOME_CANVAS_ITEM_NO_AUTO_REDRAW;
103 }
104
105 static void 
106 gnome_canvas_ruler_reset_bounds (GnomeCanvasItem *item)
107
108 {
109         double x1, x2, y1, y2;
110         ArtPoint i1, i2;
111         ArtPoint w1, w2;
112         int Ix1, Ix2, Iy1, Iy2;
113         double i2w[6];
114
115         gnome_canvas_ruler_bounds (item, &x1, &y1, &x2, &y2);
116
117         i1.x = x1;
118         i1.y = y1;
119         i2.x = x2;
120         i2.y = y2;
121
122         gnome_canvas_item_i2w_affine (item, i2w);
123         art_affine_point (&w1, &i1, i2w);
124         art_affine_point (&w2, &i2, i2w);
125
126         Ix1 = (int) rint(w1.x);
127         Ix2 = (int) rint(w2.x);
128         Iy1 = (int) rint(w1.y);
129         Iy2 = (int) rint(w2.y);
130
131         gnome_canvas_update_bbox (item, Ix1, Iy1, Ix2, Iy2);
132 }
133
134 /* 
135  * CANVAS CALLBACKS 
136  */
137
138 static void
139 gnome_canvas_ruler_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
140 {
141         GnomeCanvasItem *item;
142         GnomeCanvasRuler *ruler;
143         int redraw;
144         int calc_bounds;
145
146         item = GNOME_CANVAS_ITEM (object);
147         ruler = GNOME_CANVAS_RULER (object);
148
149         redraw = FALSE;
150         calc_bounds = FALSE;
151
152         switch (arg_id) {
153         case ARG_X1:
154                 if (ruler->x1 != GTK_VALUE_DOUBLE (*arg)) {
155                         ruler->x1 = GTK_VALUE_DOUBLE (*arg);
156                         calc_bounds = TRUE;
157                 }
158                 break;
159
160         case ARG_Y1:
161                 if (ruler->y1 != GTK_VALUE_DOUBLE (*arg)) {
162                         ruler->y1 = GTK_VALUE_DOUBLE (*arg);
163                         calc_bounds = TRUE;
164                 }
165                 break;
166
167         case ARG_X2:
168                 if (ruler->x2 != GTK_VALUE_DOUBLE (*arg)) {
169                         ruler->x2 = GTK_VALUE_DOUBLE (*arg);
170                         calc_bounds = TRUE;
171                 }
172                 break;
173
174         case ARG_Y2:
175                 if (ruler->y2 != GTK_VALUE_DOUBLE (*arg)) {
176                         ruler->y2 = GTK_VALUE_DOUBLE (*arg);
177                         calc_bounds = TRUE;
178                 }
179                 break;
180
181         case ARG_FRAMES_PER_UNIT:
182                 if (ruler->frames_per_unit != GTK_VALUE_LONG(*arg)) {
183                         ruler->frames_per_unit = GTK_VALUE_LONG(*arg);
184                         redraw = TRUE;
185                 }
186                 break;
187
188         case ARG_FILL_COLOR:
189                 if (ruler->fill_color != GTK_VALUE_INT(*arg)) {
190                         ruler->fill_color = GTK_VALUE_INT(*arg);
191                         redraw = TRUE;
192                 }
193                 break;
194
195         case ARG_TICK_COLOR:
196                 if (ruler->tick_color != GTK_VALUE_INT(*arg)) {
197                         ruler->tick_color = GTK_VALUE_INT(*arg);
198                         redraw = TRUE;
199                 }
200                 break;
201
202         default:
203                 break;
204         }
205
206         if (calc_bounds) {
207                 gnome_canvas_ruler_reset_bounds (item);
208         }
209
210         if (redraw) {
211                 gnome_canvas_item_request_update (item);
212         }
213
214 }
215
216 static void
217 gnome_canvas_ruler_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
218 {
219         GnomeCanvasRuler *ruler;
220
221         ruler = GNOME_CANVAS_RULER (object);
222
223         switch (arg_id) {
224         case ARG_X1:
225                 GTK_VALUE_DOUBLE (*arg) = ruler->x1;
226                 break;
227         case ARG_Y1:
228                 GTK_VALUE_DOUBLE (*arg) = ruler->y1;
229                 break;
230         case ARG_X2:
231                 GTK_VALUE_DOUBLE (*arg) = ruler->x2;
232                 break;
233         case ARG_Y2:
234                 GTK_VALUE_DOUBLE (*arg) = ruler->y2;
235                 break;
236         case ARG_FRAMES_PER_UNIT:
237                 GTK_VALUE_LONG (*arg) = ruler->frames_per_unit;
238                 break;
239         case ARG_FILL_COLOR:
240                 GTK_VALUE_INT (*arg) = ruler->fill_color;
241                 break;
242         case ARG_TICK_COLOR:
243                 GTK_VALUE_INT (*arg) = ruler->tick_color;
244                 break;
245         default:
246                 arg->type = GTK_TYPE_INVALID;
247                 break;
248         }
249 }
250
251 static void
252 gnome_canvas_ruler_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
253 {
254         GnomeCanvasRuler *ruler;
255         double x;
256         double y;
257
258         ruler = GNOME_CANVAS_RULER (item);
259
260         if (parent_class->update)
261                 (* parent_class->update) (item, affine, clip_path, flags);
262
263         gnome_canvas_ruler_reset_bounds (item);
264
265         x = ruler->x1;
266         y = ruler->y1;
267
268         gnome_canvas_item_i2w (item, &x, &y);
269         gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x, y, &ruler->bbox_ulx, &ruler->bbox_uly);
270
271         x = ruler->x2;
272         y = ruler->y2;
273
274         gnome_canvas_item_i2w (item, &x, &y);
275         gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x, y, &ruler->bbox_lrx, &ruler->bbox_lry);
276
277         UINT_TO_RGB (ruler->tick_color, &ruler->tick_r, &ruler->tick_g, &ruler->tick_b);
278         UINT_TO_RGB (ruler->fill_color, &ruler->fill_r, &ruler->fill_g, &ruler->fill_b);
279 }
280
281 static void
282 gnome_canvas_ruler_render (GnomeCanvasItem *item,
283                               GnomeCanvasBuf *buf)
284 {
285         GnomeCanvasRuler *ruler;
286         int end, begin;
287
288         ruler = GNOME_CANVAS_RULER (item);
289
290         if (parent_class->render) {
291                 (*parent_class->render) (item, buf);
292         }
293
294         if (buf->is_bg) {
295                 gnome_canvas_buf_ensure_buf (buf);
296                 buf->is_bg = FALSE;
297         }
298
299         begin = MAX(ruler->bbox_ulx,buf->rect.x0);
300
301         if (ruler->bbox_lrx >= 0) {
302                 end = MIN(ruler->bbox_lrx,buf->rect.x1);
303         } else {
304                 end = buf->rect.x1;
305         }
306
307         if (begin == end) {
308                 return;
309         }
310
311         PAINT_BOX (buf, ruler->fill_r, ruler->fill_g, ruler->fill_b, 255, begin, ruler->bbox_uly, end, ruler->bbox_lry - 1);
312         PAINT_HORIZ (buf, ruler->tick_r, ruler->tick_g, ruler->tick_b, begin, end, ruler->bbox_lry - 1);
313 }
314
315 static void
316 gnome_canvas_ruler_draw (GnomeCanvasItem *item,
317                             GdkDrawable *drawable,
318                             int x, int y,
319                             int width, int height)
320 {
321         GnomeCanvasRuler *ruler;
322
323         ruler = GNOME_CANVAS_RULER (item);
324
325         if (parent_class->draw) {
326                 (* parent_class->draw) (item, drawable, x, y, width, height);
327         }
328
329         fprintf (stderr, "please don't use the CanvasRuler item in a non-aa Canvas\n");
330         abort ();
331 }
332
333 static void
334 gnome_canvas_ruler_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
335 {
336         GnomeCanvasRuler *ruler = GNOME_CANVAS_RULER (item);
337
338         *x1 = ruler->x1;
339         *y1 = ruler->y1;
340         *x2 = ruler->x2;
341         *y2 = ruler->y2;
342 }
343
344 static double
345 gnome_canvas_ruler_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item)
346 {
347         GnomeCanvasRuler *ruler;
348         double x1, y1, x2, y2;
349         double dx, dy;
350
351         ruler = GNOME_CANVAS_RULER (item);
352
353         *actual_item = item;
354
355         /* Find the bounds for the rectangle plus its outline width */
356
357         gnome_canvas_ruler_bounds (item, &x1, &y1, &x2, &y2);
358
359         /* Is point inside rectangle */
360         
361         if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
362                 return 0.0;
363         }
364
365         /* Point is outside rectangle */
366
367         if (x < x1)
368                 dx = x1 - x;
369         else if (x > x2)
370                 dx = x - x2;
371         else
372                 dx = 0.0;
373
374         if (y < y1)
375                 dy = y1 - y;
376         else if (y > y2)
377                 dy = y - y2;
378         else
379                 dy = 0.0;
380
381         return sqrt (dx * dx + dy * dy);
382 }