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> */
31 #define _(Text) dgettext (PACKAGE,Text)
33 #include "gtk-custom-ruler.h"
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
,
56 static void gtk_custom_ruler_get_property (GObject
*object
,
63 default_metric_get_marks (GtkCustomRulerMark
**marks
, gdouble lower
, gdouble upper
, gint maxchars
)
68 static const GtkCustomMetric default_metric
= {
70 default_metric_get_marks
73 static GtkWidgetClass
*parent_class
;
75 GType
gtk_custom_ruler_get_type (void)
77 static GType ruler_type
= 0;
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
),
91 (GInstanceInitFunc
) gtk_custom_ruler_init
,
94 ruler_type
= g_type_register_static (GTK_TYPE_WIDGET
, "GtkCustomRuler",
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
,
125 g_param_spec_double ("lower",
127 _("Lower limit of ruler"),
133 g_object_class_install_property (gobject_class
,
135 g_param_spec_double ("upper",
137 _("Upper limit of ruler"),
143 g_object_class_install_property (gobject_class
,
145 g_param_spec_double ("position",
147 _("Position of mark on the ruler"),
153 g_object_class_install_property (gobject_class
,
155 g_param_spec_double ("max_size",
157 _("Maximum size of the ruler"),
163 g_object_class_install_property (gobject_class
,
165 g_param_spec_boolean ("show_position",
167 _("Draw current ruler position"),
173 gtk_custom_ruler_init (GtkCustomRuler
* ruler
)
175 ruler
->backing_store
= NULL
;
176 ruler
->non_gr_exp_gc
= NULL
;
179 ruler
->slider_size
= 0;
184 ruler
->show_position
= FALSE
;
186 gtk_custom_ruler_set_metric (ruler
, NULL
);
190 gtk_custom_ruler_set_property (GObject
*object
,
195 GtkCustomRuler
*ruler
= GTK_CUSTOM_RULER (object
);
200 gtk_custom_ruler_set_range (ruler
, g_value_get_double (value
), ruler
->upper
,
201 ruler
->position
, ruler
->max_size
);
204 gtk_custom_ruler_set_range (ruler
, ruler
->lower
, g_value_get_double (value
),
205 ruler
->position
, ruler
->max_size
);
208 gtk_custom_ruler_set_range (ruler
, ruler
->lower
, ruler
->upper
,
209 g_value_get_double (value
), ruler
->max_size
);
212 gtk_custom_ruler_set_range (ruler
, ruler
->lower
, ruler
->upper
,
213 ruler
->position
, g_value_get_double (value
));
215 case PROP_SHOW_POSITION
:
216 gtk_custom_ruler_set_show_position (ruler
, g_value_get_boolean (value
));
222 gtk_custom_ruler_get_property (GObject
*object
,
227 GtkCustomRuler
*ruler
= GTK_CUSTOM_RULER (object
);
232 g_value_set_double (value
, ruler
->lower
);
235 g_value_set_double (value
, ruler
->upper
);
238 g_value_set_double (value
, ruler
->position
);
241 g_value_set_double (value
, ruler
->max_size
);
243 case PROP_SHOW_POSITION
:
244 g_value_set_boolean (value
, ruler
->show_position
);
247 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
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
));
259 ruler
->metric
= (GtkCustomMetric
*) & default_metric
;
261 ruler
->metric
= metric
;
263 if (GTK_WIDGET_DRAWABLE (ruler
))
264 gtk_widget_queue_draw (GTK_WIDGET (ruler
));
268 gtk_custom_ruler_set_range (GtkCustomRuler
*ruler
,
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().
316 gtk_custom_ruler_get_range (GtkCustomRuler
*ruler
,
322 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler
));
325 *lower
= ruler
->lower
;
327 *upper
= ruler
->upper
;
329 *position
= ruler
->position
;
331 *max_size
= ruler
->max_size
;
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
);
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
);
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
);
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
);
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
);
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
);
449 gtk_custom_ruler_make_pixmap (GtkCustomRuler
*ruler
)
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
))
464 g_object_unref (ruler
->backing_store
);
467 ruler
->backing_store
= gdk_pixmap_new (widget
->window
,
468 widget
->allocation
.width
,
469 widget
->allocation
.height
,
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
);
483 gtk_custom_ruler_set_show_position (GtkCustomRuler
* ruler
, gboolean yn
)
485 ruler
->show_position
= yn
;