1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998, 1999 Alexander Larsson
4 * diaunitspinner.[ch] -- a spin button widget for length measurements.
5 * Copyright (C) 1999 James Henstridge
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #error "Moved to lib/widgets.[hc]"
26 #include <string.h> /* strcmp */
27 #include "diaunitspinner.h"
28 #include <gdk/gdkkeysyms.h>
30 typedef struct _DiaUnitDef DiaUnitDef
;
37 /* from gnome-libs/libgnome/gnome-paper.c */
38 static const DiaUnitDef units
[] =
40 /* XXX does anyone *really* measure paper size in feet? meters? */
42 /* human name, abreviation, points per unit */
43 { "Feet", "ft", 864 },
44 { "Meter", "m", 2834.6457 },
45 { "Decimeter", "dm", 283.46457 },
46 { "Millimeter", "mm", 2.8346457 },
47 { "Point", "pt", 1. },
48 { "Centimeter", "cm", 28.346457 },
54 static GtkObjectClass
*parent_class
;
55 static GtkObjectClass
*entry_class
;
57 static void dia_unit_spinner_class_init(DiaUnitSpinnerClass
*class);
58 static void dia_unit_spinner_init(DiaUnitSpinner
*self
);
61 dia_unit_spinner_get_type(void)
63 static GtkType us_type
= 0;
66 GtkTypeInfo us_info
= {
68 sizeof(DiaUnitSpinner
),
69 sizeof(DiaUnitSpinnerClass
),
70 (GtkClassInitFunc
) dia_unit_spinner_class_init
,
71 (GtkObjectInitFunc
) dia_unit_spinner_init
,
74 (GtkClassInitFunc
) NULL
,
76 us_type
= gtk_type_unique(gtk_spin_button_get_type(), &us_info
);
82 dia_unit_spinner_value_changed(GtkAdjustment
*adjustment
,
83 DiaUnitSpinner
*spinner
)
86 GtkSpinButton
*sbutton
= GTK_SPIN_BUTTON(spinner
);
88 g_snprintf(buf
, sizeof(buf
), "%0.*f%s", sbutton
->digits
, adjustment
->value
,
89 units
[spinner
->unit_num
].unit
);
90 if (strcmp(buf
, gtk_entry_get_text(GTK_ENTRY(spinner
))))
91 gtk_entry_set_text(GTK_ENTRY(spinner
), buf
);
94 static gint
dia_unit_spinner_focus_out(GtkWidget
*widget
, GdkEventFocus
*ev
);
95 static gint
dia_unit_spinner_button_press(GtkWidget
*widget
,GdkEventButton
*ev
);
96 static gint
dia_unit_spinner_key_press(GtkWidget
*widget
, GdkEventKey
*event
);
97 static void dia_unit_spinner_activate(GtkEntry
*editable
);
100 dia_unit_spinner_class_init(DiaUnitSpinnerClass
*class)
102 GtkObjectClass
*object_class
;
103 GtkWidgetClass
*widget_class
;
104 GtkEntryClass
*editable_class
;
106 object_class
= (GtkObjectClass
*)class;
107 widget_class
= (GtkWidgetClass
*)class;
108 editable_class
= (GtkEntryClass
*)class;
110 widget_class
->focus_out_event
= dia_unit_spinner_focus_out
;
111 widget_class
->button_press_event
= dia_unit_spinner_button_press
;
112 widget_class
->key_press_event
= dia_unit_spinner_key_press
;
113 editable_class
->activate
= dia_unit_spinner_activate
;
115 parent_class
= gtk_type_class(GTK_TYPE_SPIN_BUTTON
);
116 entry_class
= gtk_type_class(GTK_TYPE_ENTRY
);
120 dia_unit_spinner_init(DiaUnitSpinner
*self
)
122 /* change over to our own print function that appends the unit name on the
124 if (self
->parent
.adjustment
) {
125 gtk_signal_disconnect_by_data(GTK_OBJECT(self
->parent
.adjustment
),
127 g_signal_connect(GTK_OBJECT(self
->parent
.adjustment
), "value_changed",
128 G_CALLBACK(dia_unit_spinner_value_changed
),
132 self
->unit_num
= DIA_UNIT_CENTIMETER
;
136 dia_unit_spinner_new(GtkAdjustment
*adjustment
, guint digits
, DiaUnit adj_unit
)
138 DiaUnitSpinner
*self
= gtk_type_new(dia_unit_spinner_get_type());
140 gtk_spin_button_configure(GTK_SPIN_BUTTON(self
), adjustment
, 0.0, digits
);
143 gtk_signal_disconnect_by_data(GTK_OBJECT(adjustment
),
145 g_signal_connect(GTK_OBJECT(adjustment
), "value_changed",
146 G_CALLBACK(dia_unit_spinner_value_changed
),
150 self
->unit_num
= adj_unit
;
152 return GTK_WIDGET(self
);
156 dia_unit_spinner_set_value(DiaUnitSpinner
*self
, gfloat val
)
158 GtkSpinButton
*sbutton
= GTK_SPIN_BUTTON(self
);
160 if (val
< sbutton
->adjustment
->lower
)
161 val
= sbutton
->adjustment
->lower
;
162 else if (val
> sbutton
->adjustment
->upper
)
163 val
= sbutton
->adjustment
->upper
;
164 if (val
!= sbutton
->adjustment
->value
) {
165 sbutton
->adjustment
->value
= val
;
166 gtk_adjustment_value_changed(sbutton
->adjustment
);
171 dia_unit_spinner_get_value(DiaUnitSpinner
*self
)
173 GtkSpinButton
*sbutton
= GTK_SPIN_BUTTON(self
);
175 return sbutton
->adjustment
->value
;
179 dia_unit_spinner_update(DiaUnitSpinner
*self
)
181 GtkSpinButton
*sbutton
= GTK_SPIN_BUTTON(self
);
182 gfloat val
, factor
= 1.0;
185 val
= g_strtod(gtk_entry_get_text(GTK_ENTRY(self
)), &extra
);
187 /* get rid of extra white space after number */
188 while (*extra
&& g_ascii_isspace(*extra
)) extra
++;
192 for (i
= 0; units
[i
].name
!= NULL
; i
++)
193 if (!g_strcasecmp(units
[i
].unit
, extra
)) {
194 factor
= units
[i
].factor
/ units
[self
->unit_num
].factor
;
198 /* convert to prefered units */
200 if (val
< sbutton
->adjustment
->lower
)
201 val
= sbutton
->adjustment
->lower
;
202 else if (val
> sbutton
->adjustment
->upper
)
203 val
= sbutton
->adjustment
->upper
;
204 gtk_adjustment_set_value(sbutton
->adjustment
, val
);
208 dia_unit_spinner_focus_out(GtkWidget
*widget
, GdkEventFocus
*event
)
210 if (GTK_ENTRY (widget
)->editable
)
211 dia_unit_spinner_update(DIA_UNIT_SPINNER(widget
));
212 return GTK_WIDGET_CLASS(entry_class
)->focus_out_event(widget
, event
);
216 dia_unit_spinner_button_press(GtkWidget
*widget
, GdkEventButton
*event
)
218 dia_unit_spinner_update(DIA_UNIT_SPINNER(widget
));
219 return GTK_WIDGET_CLASS(parent_class
)->button_press_event(widget
, event
);
223 dia_unit_spinner_key_press(GtkWidget
*widget
, GdkEventKey
*event
)
225 gint key
= event
->keyval
;
227 if (GTK_ENTRY (widget
)->editable
&&
228 (key
== GDK_Up
|| key
== GDK_Down
||
229 key
== GDK_Page_Up
|| key
== GDK_Page_Down
))
230 dia_unit_spinner_update (DIA_UNIT_SPINNER(widget
));
231 return GTK_WIDGET_CLASS(parent_class
)->key_press_event(widget
, event
);
235 dia_unit_spinner_activate(GtkEntry
*editable
)
237 if (editable
->editable
)
238 dia_unit_spinner_update(DIA_UNIT_SPINNER(editable
));