Just some CVS ignore stuff.
[dia.git] / app / diaunitspinner.c
blob9dd9a361a2369d0d5672b4d1a02a3131ed0b6a26
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.
22 #include <config.h>
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;
31 struct _DiaUnitDef {
32 char* name;
33 char* unit;
34 float factor;
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 },
49 { "Inch", "in", 72 },
50 { "Pica", "pi", 12 },
51 { 0 }
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);
60 GtkType
61 dia_unit_spinner_get_type(void)
63 static GtkType us_type = 0;
65 if (!us_type) {
66 GtkTypeInfo us_info = {
67 "DiaUnitSpinner",
68 sizeof(DiaUnitSpinner),
69 sizeof(DiaUnitSpinnerClass),
70 (GtkClassInitFunc) dia_unit_spinner_class_init,
71 (GtkObjectInitFunc) dia_unit_spinner_init,
72 NULL,
73 NULL,
74 (GtkClassInitFunc) NULL,
76 us_type = gtk_type_unique(gtk_spin_button_get_type(), &us_info);
78 return us_type;
81 static void
82 dia_unit_spinner_value_changed(GtkAdjustment *adjustment,
83 DiaUnitSpinner *spinner)
85 char buf[256];
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);
99 static void
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);
119 static void
120 dia_unit_spinner_init(DiaUnitSpinner *self)
122 /* change over to our own print function that appends the unit name on the
123 * end */
124 if (self->parent.adjustment) {
125 gtk_signal_disconnect_by_data(GTK_OBJECT(self->parent.adjustment),
126 (gpointer) self);
127 g_signal_connect(GTK_OBJECT(self->parent.adjustment), "value_changed",
128 G_CALLBACK(dia_unit_spinner_value_changed),
129 (gpointer) self);
132 self->unit_num = DIA_UNIT_CENTIMETER;
135 GtkWidget *
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);
142 if (adjustment) {
143 gtk_signal_disconnect_by_data(GTK_OBJECT(adjustment),
144 (gpointer) self);
145 g_signal_connect(GTK_OBJECT(adjustment), "value_changed",
146 G_CALLBACK(dia_unit_spinner_value_changed),
147 (gpointer) self);
150 self->unit_num = adj_unit;
152 return GTK_WIDGET(self);
155 void
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);
170 gfloat
171 dia_unit_spinner_get_value(DiaUnitSpinner *self)
173 GtkSpinButton *sbutton = GTK_SPIN_BUTTON(self);
175 return sbutton->adjustment->value;
178 static void
179 dia_unit_spinner_update(DiaUnitSpinner *self)
181 GtkSpinButton *sbutton = GTK_SPIN_BUTTON(self);
182 gfloat val, factor = 1.0;
183 gchar *extra = NULL;
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++;
189 if (*extra) {
190 int i;
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;
195 break;
198 /* convert to prefered units */
199 val *= factor;
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);
207 static gint
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);
215 static gint
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);
222 static gint
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);
234 static void
235 dia_unit_spinner_activate(GtkEntry *editable)
237 if (editable->editable)
238 dia_unit_spinner_update(DIA_UNIT_SPINNER(editable));