clean up & extend handling of various AU Component types & subtypes - makes AU NetSen...
[ardour2.git] / gtk2_ardour / gtk-custom-ruler.c
blob0e7ceb5875b3dc360874eea9831bee75e4058e9b
1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
27 /* modified by andreas meyer <hexx3000@gmx.de> */
29 #include <stdio.h>
30 #include "gettext.h"
31 #define _(Text) dgettext (PACKAGE,Text)
33 #include "gtk-custom-ruler.h"
35 enum
37 PROP_0,
38 PROP_LOWER,
39 PROP_UPPER,
40 PROP_POSITION,
41 PROP_MAX_SIZE,
42 PROP_SHOW_POSITION
45 static void gtk_custom_ruler_class_init (GtkCustomRulerClass * klass);
46 static void gtk_custom_ruler_init (GtkCustomRuler * ruler);
47 static void gtk_custom_ruler_realize (GtkWidget * widget);
48 static void gtk_custom_ruler_unrealize (GtkWidget * widget);
49 static void gtk_custom_ruler_size_allocate (GtkWidget * widget, GtkAllocation * allocation);
50 static gint gtk_custom_ruler_expose (GtkWidget * widget, GdkEventExpose * event);
51 static void gtk_custom_ruler_make_pixmap (GtkCustomRuler * ruler);
52 static void gtk_custom_ruler_set_property (GObject *object,
53 guint prop_id,
54 const GValue *value,
55 GParamSpec *pspec);
56 static void gtk_custom_ruler_get_property (GObject *object,
57 guint prop_id,
58 GValue *value,
59 GParamSpec *pspec);
62 static gint
63 default_metric_get_marks (GtkCustomRulerMark **marks, gdouble lower, gdouble upper, gint maxchars)
65 return 0;
68 static const GtkCustomMetric default_metric = {
69 1.0,
70 default_metric_get_marks
73 static GtkWidgetClass *parent_class;
75 GType gtk_custom_ruler_get_type (void)
77 static GType ruler_type = 0;
79 if (!ruler_type)
81 static const GTypeInfo ruler_info =
83 sizeof (GtkCustomRulerClass),
84 (GBaseInitFunc) NULL, /* base_init */
85 (GBaseFinalizeFunc) NULL, /* base_finalize */
86 (GClassInitFunc) gtk_custom_ruler_class_init,
87 (GClassFinalizeFunc) NULL, /* class_finalize */
88 NULL, /* class_data */
89 sizeof (GtkCustomRuler),
90 0, /* n_preallocs */
91 (GInstanceInitFunc) gtk_custom_ruler_init,
94 ruler_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkCustomRuler",
95 &ruler_info, 0);
98 return ruler_type;
101 static void
102 gtk_custom_ruler_class_init (GtkCustomRulerClass * class)
104 GObjectClass *gobject_class;
105 GtkWidgetClass *widget_class;
107 gobject_class = (GObjectClass *) class;
108 widget_class = (GtkWidgetClass*) class;
110 parent_class = g_type_class_peek_parent (class);
112 gobject_class->set_property = gtk_custom_ruler_set_property;
113 gobject_class->get_property = gtk_custom_ruler_get_property;
115 widget_class->realize = gtk_custom_ruler_realize;
116 widget_class->unrealize = gtk_custom_ruler_unrealize;
117 widget_class->size_allocate = gtk_custom_ruler_size_allocate;
118 widget_class->expose_event = gtk_custom_ruler_expose;
120 class->draw_ticks = NULL;
121 class->draw_pos = NULL;
123 g_object_class_install_property (gobject_class,
124 PROP_LOWER,
125 g_param_spec_double ("lower",
126 _("Lower"),
127 _("Lower limit of ruler"),
128 -G_MAXDOUBLE,
129 G_MAXDOUBLE,
130 0.0,
131 G_PARAM_READWRITE));
133 g_object_class_install_property (gobject_class,
134 PROP_UPPER,
135 g_param_spec_double ("upper",
136 _("Upper"),
137 _("Upper limit of ruler"),
138 -G_MAXDOUBLE,
139 G_MAXDOUBLE,
140 0.0,
141 G_PARAM_READWRITE));
143 g_object_class_install_property (gobject_class,
144 PROP_POSITION,
145 g_param_spec_double ("position",
146 _("Position"),
147 _("Position of mark on the ruler"),
148 -G_MAXDOUBLE,
149 G_MAXDOUBLE,
150 0.0,
151 G_PARAM_READWRITE));
153 g_object_class_install_property (gobject_class,
154 PROP_MAX_SIZE,
155 g_param_spec_double ("max_size",
156 _("Max Size"),
157 _("Maximum size of the ruler"),
158 -G_MAXDOUBLE,
159 G_MAXDOUBLE,
160 0.0,
161 G_PARAM_READWRITE));
163 g_object_class_install_property (gobject_class,
164 PROP_SHOW_POSITION,
165 g_param_spec_boolean ("show_position",
166 _("Show Position"),
167 _("Draw current ruler position"),
168 TRUE,
169 G_PARAM_READWRITE));
172 static void
173 gtk_custom_ruler_init (GtkCustomRuler * ruler)
175 ruler->backing_store = NULL;
176 ruler->non_gr_exp_gc = NULL;
177 ruler->xsrc = 0;
178 ruler->ysrc = 0;
179 ruler->slider_size = 0;
180 ruler->lower = 0;
181 ruler->upper = 0;
182 ruler->position = 0;
183 ruler->max_size = 0;
184 ruler->show_position = FALSE;
186 gtk_custom_ruler_set_metric (ruler, NULL);
189 static void
190 gtk_custom_ruler_set_property (GObject *object,
191 guint prop_id,
192 const GValue *value,
193 GParamSpec *pspec)
195 GtkCustomRuler *ruler = GTK_CUSTOM_RULER (object);
197 switch (prop_id)
199 case PROP_LOWER:
200 gtk_custom_ruler_set_range (ruler, g_value_get_double (value), ruler->upper,
201 ruler->position, ruler->max_size);
202 break;
203 case PROP_UPPER:
204 gtk_custom_ruler_set_range (ruler, ruler->lower, g_value_get_double (value),
205 ruler->position, ruler->max_size);
206 break;
207 case PROP_POSITION:
208 gtk_custom_ruler_set_range (ruler, ruler->lower, ruler->upper,
209 g_value_get_double (value), ruler->max_size);
210 break;
211 case PROP_MAX_SIZE:
212 gtk_custom_ruler_set_range (ruler, ruler->lower, ruler->upper,
213 ruler->position, g_value_get_double (value));
214 break;
215 case PROP_SHOW_POSITION:
216 gtk_custom_ruler_set_show_position (ruler, g_value_get_boolean (value));
217 break;
221 static void
222 gtk_custom_ruler_get_property (GObject *object,
223 guint prop_id,
224 GValue *value,
225 GParamSpec *pspec)
227 GtkCustomRuler *ruler = GTK_CUSTOM_RULER (object);
229 switch (prop_id)
231 case PROP_LOWER:
232 g_value_set_double (value, ruler->lower);
233 break;
234 case PROP_UPPER:
235 g_value_set_double (value, ruler->upper);
236 break;
237 case PROP_POSITION:
238 g_value_set_double (value, ruler->position);
239 break;
240 case PROP_MAX_SIZE:
241 g_value_set_double (value, ruler->max_size);
242 break;
243 case PROP_SHOW_POSITION:
244 g_value_set_boolean (value, ruler->show_position);
245 break;
246 default:
247 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
248 break;
252 void
253 gtk_custom_ruler_set_metric (GtkCustomRuler * ruler, GtkCustomMetric * metric)
255 g_return_if_fail (ruler != NULL);
256 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler));
258 if (metric == NULL)
259 ruler->metric = (GtkCustomMetric *) & default_metric;
260 else
261 ruler->metric = metric;
263 if (GTK_WIDGET_DRAWABLE (ruler))
264 gtk_widget_queue_draw (GTK_WIDGET (ruler));
267 void
268 gtk_custom_ruler_set_range (GtkCustomRuler *ruler,
269 gdouble lower,
270 gdouble upper,
271 gdouble position,
272 gdouble max_size)
274 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler));
276 g_object_freeze_notify (G_OBJECT (ruler));
277 if (ruler->lower != lower)
279 ruler->lower = lower;
280 g_object_notify (G_OBJECT (ruler), "lower");
282 if (ruler->upper != upper)
284 ruler->upper = upper;
285 g_object_notify (G_OBJECT (ruler), "upper");
287 if (ruler->position != position)
289 ruler->position = position;
290 g_object_notify (G_OBJECT (ruler), "position");
292 if (ruler->max_size != max_size)
294 ruler->max_size = max_size;
295 g_object_notify (G_OBJECT (ruler), "max-size");
297 g_object_thaw_notify (G_OBJECT (ruler));
299 if (GTK_WIDGET_DRAWABLE (ruler))
300 gtk_widget_queue_draw (GTK_WIDGET (ruler));
304 * gtk_custom_ruler_get_range:
305 * @ruler: a #GtkCustomRuler
306 * @lower: location to store lower limit of the ruler, or %NULL
307 * @upper: location to store upper limit of the ruler, or %NULL
308 * @position: location to store the current position of the mark on the ruler, or %NULL
309 * @max_size: location to store the maximum size of the ruler used when calculating
310 * the space to leave for the text, or %NULL.
312 * Retrieves values indicating the range and current position of a #GtkCustomRuler.
313 * See gtk_custom_ruler_set_range().
315 void
316 gtk_custom_ruler_get_range (GtkCustomRuler *ruler,
317 gdouble *lower,
318 gdouble *upper,
319 gdouble *position,
320 gdouble *max_size)
322 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler));
324 if (lower)
325 *lower = ruler->lower;
326 if (upper)
327 *upper = ruler->upper;
328 if (position)
329 *position = ruler->position;
330 if (max_size)
331 *max_size = ruler->max_size;
334 void
335 gtk_custom_ruler_draw_ticks (GtkCustomRuler * ruler)
337 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler));
339 if (GTK_CUSTOM_RULER_GET_CLASS (ruler)->draw_ticks)
340 GTK_CUSTOM_RULER_GET_CLASS (ruler)->draw_ticks (ruler);
344 void
345 gtk_custom_ruler_draw_pos (GtkCustomRuler * ruler)
347 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler));
349 if (GTK_CUSTOM_RULER_GET_CLASS (ruler)->draw_pos && ruler->show_position)
350 GTK_CUSTOM_RULER_GET_CLASS (ruler)->draw_pos (ruler);
353 static void
354 gtk_custom_ruler_realize (GtkWidget * widget)
356 GtkCustomRuler *ruler;
357 GdkWindowAttr attributes;
358 gint attributes_mask;
360 g_return_if_fail (widget != NULL);
361 g_return_if_fail (GTK_IS_CUSTOM_RULER (widget));
363 ruler = GTK_CUSTOM_RULER (widget);
364 GTK_WIDGET_SET_FLAGS (ruler, GTK_REALIZED);
366 attributes.window_type = GDK_WINDOW_CHILD;
367 attributes.x = widget->allocation.x;
368 attributes.y = widget->allocation.y;
369 attributes.width = widget->allocation.width;
370 attributes.height = widget->allocation.height;
371 attributes.wclass = GDK_INPUT_OUTPUT;
372 attributes.visual = gtk_widget_get_visual (widget);
373 attributes.colormap = gtk_widget_get_colormap (widget);
374 attributes.event_mask = gtk_widget_get_events (widget);
375 attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
377 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
379 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
380 gdk_window_set_user_data (widget->window, ruler);
382 widget->style = gtk_style_attach (widget->style, widget->window);
383 gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
385 gtk_custom_ruler_make_pixmap (ruler);
388 static void
389 gtk_custom_ruler_unrealize (GtkWidget *widget)
391 GtkCustomRuler *ruler = GTK_CUSTOM_RULER (widget);
393 if (ruler->backing_store)
394 g_object_unref (ruler->backing_store);
395 if (ruler->non_gr_exp_gc)
396 g_object_unref (ruler->non_gr_exp_gc);
398 ruler->backing_store = NULL;
399 ruler->non_gr_exp_gc = NULL;
401 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
402 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
405 static void
406 gtk_custom_ruler_size_allocate (GtkWidget *widget,
407 GtkAllocation *allocation)
409 GtkCustomRuler *ruler = GTK_CUSTOM_RULER (widget);
411 widget->allocation = *allocation;
413 if (GTK_WIDGET_REALIZED (widget))
415 gdk_window_move_resize (widget->window,
416 allocation->x, allocation->y,
417 allocation->width, allocation->height);
419 gtk_custom_ruler_make_pixmap (ruler);
423 static gint
424 gtk_custom_ruler_expose (GtkWidget * widget, GdkEventExpose * event)
426 GtkCustomRuler *ruler;
428 g_return_val_if_fail (widget != NULL, FALSE);
429 g_return_val_if_fail (GTK_IS_CUSTOM_RULER (widget), FALSE);
430 g_return_val_if_fail (event != NULL, FALSE);
432 if (GTK_WIDGET_DRAWABLE (widget)) {
433 ruler = GTK_CUSTOM_RULER (widget);
435 gtk_custom_ruler_draw_ticks (ruler);
437 gdk_draw_pixmap (widget->window,
438 ruler->non_gr_exp_gc,
439 ruler->backing_store, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height);
441 gtk_custom_ruler_draw_pos (ruler);
444 return FALSE;
448 static void
449 gtk_custom_ruler_make_pixmap (GtkCustomRuler *ruler)
451 GtkWidget *widget;
452 gint width;
453 gint height;
455 widget = GTK_WIDGET (ruler);
457 if (ruler->backing_store)
459 gdk_drawable_get_size (ruler->backing_store, &width, &height);
460 if ((width == widget->allocation.width) &&
461 (height == widget->allocation.height))
462 return;
464 g_object_unref (ruler->backing_store);
467 ruler->backing_store = gdk_pixmap_new (widget->window,
468 widget->allocation.width,
469 widget->allocation.height,
470 -1);
472 ruler->xsrc = 0;
473 ruler->ysrc = 0;
475 if (!ruler->non_gr_exp_gc)
477 ruler->non_gr_exp_gc = gdk_gc_new (widget->window);
478 gdk_gc_set_exposures (ruler->non_gr_exp_gc, FALSE);
482 void
483 gtk_custom_ruler_set_show_position (GtkCustomRuler * ruler, gboolean yn)
485 ruler->show_position = yn;