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
)
73 static const GtkCustomMetric default_metric
= {
75 default_metric_get_marks
78 static GtkWidgetClass
*parent_class
;
80 GType
gtk_custom_ruler_get_type (void)
82 static GType ruler_type
= 0;
86 static const GTypeInfo ruler_info
=
88 sizeof (GtkCustomRulerClass
),
89 (GBaseInitFunc
) NULL
, /* base_init */
90 (GBaseFinalizeFunc
) NULL
, /* base_finalize */
91 (GClassInitFunc
) gtk_custom_ruler_class_init
,
92 (GClassFinalizeFunc
) NULL
, /* class_finalize */
93 NULL
, /* class_data */
94 sizeof (GtkCustomRuler
),
96 (GInstanceInitFunc
) gtk_custom_ruler_init
,
97 NULL
/* value_table */
100 ruler_type
= g_type_register_static (GTK_TYPE_WIDGET
, "GtkCustomRuler",
108 gtk_custom_ruler_class_init (GtkCustomRulerClass
* class)
110 GObjectClass
*gobject_class
;
111 GtkWidgetClass
*widget_class
;
113 gobject_class
= (GObjectClass
*) class;
114 widget_class
= (GtkWidgetClass
*) class;
116 parent_class
= g_type_class_peek_parent (class);
118 gobject_class
->set_property
= gtk_custom_ruler_set_property
;
119 gobject_class
->get_property
= gtk_custom_ruler_get_property
;
121 widget_class
->realize
= gtk_custom_ruler_realize
;
122 widget_class
->unrealize
= gtk_custom_ruler_unrealize
;
123 widget_class
->size_allocate
= gtk_custom_ruler_size_allocate
;
124 widget_class
->expose_event
= gtk_custom_ruler_expose
;
126 class->draw_ticks
= NULL
;
127 class->draw_pos
= NULL
;
129 g_object_class_install_property (gobject_class
,
131 g_param_spec_double ("lower",
133 _("Lower limit of ruler"),
139 g_object_class_install_property (gobject_class
,
141 g_param_spec_double ("upper",
143 _("Upper limit of ruler"),
149 g_object_class_install_property (gobject_class
,
151 g_param_spec_double ("position",
153 _("Position of mark on the ruler"),
159 g_object_class_install_property (gobject_class
,
161 g_param_spec_double ("max_size",
163 _("Maximum size of the ruler"),
169 g_object_class_install_property (gobject_class
,
171 g_param_spec_boolean ("show_position",
173 _("Draw current ruler position"),
179 gtk_custom_ruler_init (GtkCustomRuler
* ruler
)
181 ruler
->backing_store
= NULL
;
182 ruler
->non_gr_exp_gc
= NULL
;
185 ruler
->slider_size
= 0;
190 ruler
->show_position
= FALSE
;
192 gtk_custom_ruler_set_metric (ruler
, NULL
);
196 gtk_custom_ruler_set_property (GObject
*object
,
203 GtkCustomRuler
*ruler
= GTK_CUSTOM_RULER (object
);
208 gtk_custom_ruler_set_range (ruler
, g_value_get_double (value
), ruler
->upper
,
209 ruler
->position
, ruler
->max_size
);
212 gtk_custom_ruler_set_range (ruler
, ruler
->lower
, g_value_get_double (value
),
213 ruler
->position
, ruler
->max_size
);
216 gtk_custom_ruler_set_range (ruler
, ruler
->lower
, ruler
->upper
,
217 g_value_get_double (value
), ruler
->max_size
);
220 gtk_custom_ruler_set_range (ruler
, ruler
->lower
, ruler
->upper
,
221 ruler
->position
, g_value_get_double (value
));
223 case PROP_SHOW_POSITION
:
224 gtk_custom_ruler_set_show_position (ruler
, g_value_get_boolean (value
));
230 gtk_custom_ruler_get_property (GObject
*object
,
235 GtkCustomRuler
*ruler
= GTK_CUSTOM_RULER (object
);
240 g_value_set_double (value
, ruler
->lower
);
243 g_value_set_double (value
, ruler
->upper
);
246 g_value_set_double (value
, ruler
->position
);
249 g_value_set_double (value
, ruler
->max_size
);
251 case PROP_SHOW_POSITION
:
252 g_value_set_boolean (value
, ruler
->show_position
);
255 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
261 gtk_custom_ruler_set_metric (GtkCustomRuler
* ruler
, GtkCustomMetric
* metric
)
263 g_return_if_fail (ruler
!= NULL
);
264 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler
));
267 ruler
->metric
= (GtkCustomMetric
*) & default_metric
;
269 ruler
->metric
= metric
;
271 if (GTK_WIDGET_DRAWABLE (ruler
))
272 gtk_widget_queue_draw (GTK_WIDGET (ruler
));
276 gtk_custom_ruler_set_range (GtkCustomRuler
*ruler
,
282 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler
));
284 g_object_freeze_notify (G_OBJECT (ruler
));
285 if (ruler
->lower
!= lower
)
287 ruler
->lower
= lower
;
288 g_object_notify (G_OBJECT (ruler
), "lower");
290 if (ruler
->upper
!= upper
)
292 ruler
->upper
= upper
;
293 g_object_notify (G_OBJECT (ruler
), "upper");
295 if (ruler
->position
!= position
)
297 ruler
->position
= position
;
298 g_object_notify (G_OBJECT (ruler
), "position");
300 if (ruler
->max_size
!= max_size
)
302 ruler
->max_size
= max_size
;
303 g_object_notify (G_OBJECT (ruler
), "max-size");
305 g_object_thaw_notify (G_OBJECT (ruler
));
307 if (GTK_WIDGET_DRAWABLE (ruler
))
308 gtk_widget_queue_draw (GTK_WIDGET (ruler
));
312 * gtk_custom_ruler_get_range:
313 * @ruler: a #GtkCustomRuler
314 * @lower: location to store lower limit of the ruler, or %NULL
315 * @upper: location to store upper limit of the ruler, or %NULL
316 * @position: location to store the current position of the mark on the ruler, or %NULL
317 * @max_size: location to store the maximum size of the ruler used when calculating
318 * the space to leave for the text, or %NULL.
320 * Retrieves values indicating the range and current position of a #GtkCustomRuler.
321 * See gtk_custom_ruler_set_range().
324 gtk_custom_ruler_get_range (GtkCustomRuler
*ruler
,
330 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler
));
333 *lower
= ruler
->lower
;
335 *upper
= ruler
->upper
;
337 *position
= ruler
->position
;
339 *max_size
= ruler
->max_size
;
343 gtk_custom_ruler_draw_ticks (GtkCustomRuler
* ruler
)
345 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler
));
347 if (GTK_CUSTOM_RULER_GET_CLASS (ruler
)->draw_ticks
)
348 GTK_CUSTOM_RULER_GET_CLASS (ruler
)->draw_ticks (ruler
);
353 gtk_custom_ruler_draw_pos (GtkCustomRuler
* ruler
)
355 g_return_if_fail (GTK_IS_CUSTOM_RULER (ruler
));
357 if (GTK_CUSTOM_RULER_GET_CLASS (ruler
)->draw_pos
&& ruler
->show_position
)
358 GTK_CUSTOM_RULER_GET_CLASS (ruler
)->draw_pos (ruler
);
362 gtk_custom_ruler_realize (GtkWidget
* widget
)
364 GtkCustomRuler
*ruler
;
365 GdkWindowAttr attributes
;
366 gint attributes_mask
;
368 g_return_if_fail (widget
!= NULL
);
369 g_return_if_fail (GTK_IS_CUSTOM_RULER (widget
));
371 ruler
= GTK_CUSTOM_RULER (widget
);
372 GTK_WIDGET_SET_FLAGS (ruler
, GTK_REALIZED
);
374 attributes
.window_type
= GDK_WINDOW_CHILD
;
375 attributes
.x
= widget
->allocation
.x
;
376 attributes
.y
= widget
->allocation
.y
;
377 attributes
.width
= widget
->allocation
.width
;
378 attributes
.height
= widget
->allocation
.height
;
379 attributes
.wclass
= GDK_INPUT_OUTPUT
;
380 attributes
.visual
= gtk_widget_get_visual (widget
);
381 attributes
.colormap
= gtk_widget_get_colormap (widget
);
382 attributes
.event_mask
= gtk_widget_get_events (widget
);
383 attributes
.event_mask
|= (GDK_EXPOSURE_MASK
| GDK_POINTER_MOTION_MASK
| GDK_POINTER_MOTION_HINT_MASK
);
385 attributes_mask
= GDK_WA_X
| GDK_WA_Y
| GDK_WA_VISUAL
| GDK_WA_COLORMAP
;
387 widget
->window
= gdk_window_new (gtk_widget_get_parent_window (widget
), &attributes
, attributes_mask
);
388 gdk_window_set_user_data (widget
->window
, ruler
);
390 widget
->style
= gtk_style_attach (widget
->style
, widget
->window
);
391 gtk_style_set_background (widget
->style
, widget
->window
, GTK_STATE_ACTIVE
);
393 gtk_custom_ruler_make_pixmap (ruler
);
397 gtk_custom_ruler_unrealize (GtkWidget
*widget
)
399 GtkCustomRuler
*ruler
= GTK_CUSTOM_RULER (widget
);
401 if (ruler
->backing_store
)
402 g_object_unref (ruler
->backing_store
);
403 if (ruler
->non_gr_exp_gc
)
404 g_object_unref (ruler
->non_gr_exp_gc
);
406 ruler
->backing_store
= NULL
;
407 ruler
->non_gr_exp_gc
= NULL
;
409 if (GTK_WIDGET_CLASS (parent_class
)->unrealize
)
410 (* GTK_WIDGET_CLASS (parent_class
)->unrealize
) (widget
);
414 gtk_custom_ruler_size_allocate (GtkWidget
*widget
,
415 GtkAllocation
*allocation
)
417 GtkCustomRuler
*ruler
= GTK_CUSTOM_RULER (widget
);
419 widget
->allocation
= *allocation
;
421 if (GTK_WIDGET_REALIZED (widget
))
423 gdk_window_move_resize (widget
->window
,
424 allocation
->x
, allocation
->y
,
425 allocation
->width
, allocation
->height
);
427 gtk_custom_ruler_make_pixmap (ruler
);
432 gtk_custom_ruler_expose (GtkWidget
* widget
, GdkEventExpose
* event
)
434 GtkCustomRuler
*ruler
;
436 g_return_val_if_fail (widget
!= NULL
, FALSE
);
437 g_return_val_if_fail (GTK_IS_CUSTOM_RULER (widget
), FALSE
);
438 g_return_val_if_fail (event
!= NULL
, FALSE
);
440 if (GTK_WIDGET_DRAWABLE (widget
)) {
441 ruler
= GTK_CUSTOM_RULER (widget
);
443 gtk_custom_ruler_draw_ticks (ruler
);
445 gdk_draw_drawable (widget
->window
,
446 ruler
->non_gr_exp_gc
,
447 GDK_DRAWABLE(ruler
->backing_store
), 0, 0, 0, 0, widget
->allocation
.width
, widget
->allocation
.height
);
449 gtk_custom_ruler_draw_pos (ruler
);
457 gtk_custom_ruler_make_pixmap (GtkCustomRuler
*ruler
)
463 widget
= GTK_WIDGET (ruler
);
465 if (ruler
->backing_store
)
467 gdk_drawable_get_size (ruler
->backing_store
, &width
, &height
);
468 if ((width
== widget
->allocation
.width
) &&
469 (height
== widget
->allocation
.height
))
472 g_object_unref (ruler
->backing_store
);
475 ruler
->backing_store
= gdk_pixmap_new (widget
->window
,
476 widget
->allocation
.width
,
477 widget
->allocation
.height
,
483 if (!ruler
->non_gr_exp_gc
)
485 ruler
->non_gr_exp_gc
= gdk_gc_new (widget
->window
);
486 gdk_gc_set_exposures (ruler
->non_gr_exp_gc
, FALSE
);
491 gtk_custom_ruler_set_show_position (GtkCustomRuler
* ruler
, gboolean yn
)
493 ruler
->show_position
= yn
;