Index: lib/widgets.c =================================================================== --- lib/widgets.c (revision 3697) +++ lib/widgets.c (working copy) @@ -1512,9 +1512,6 @@ { 0 } }; -static GtkObjectClass *parent_class; -static GtkObjectClass *entry_class; - static void dia_unit_spinner_class_init(DiaUnitSpinnerClass *class); static void dia_unit_spinner_init(DiaUnitSpinner *self); @@ -1539,61 +1536,27 @@ return us_type; } -/** Updates the spinner display to show digits and units */ -static void -dia_unit_spinner_value_changed(GtkAdjustment *adjustment, - DiaUnitSpinner *spinner) -{ - char buf[256]; - GtkSpinButton *sbutton = GTK_SPIN_BUTTON(spinner); - g_snprintf(buf, sizeof(buf), "%0.*f %s", sbutton->digits, adjustment->value, - units[spinner->unit_num].unit); - gtk_entry_set_text(GTK_ENTRY(spinner), buf); -} - -static void dia_unit_spinner_set_value_direct(DiaUnitSpinner *self, gfloat val); -static gint dia_unit_spinner_focus_out(GtkWidget *widget, GdkEventFocus *ev); -static gint dia_unit_spinner_button_press(GtkWidget *widget,GdkEventButton*ev); -static gint dia_unit_spinner_key_press(GtkWidget *widget, GdkEventKey *event); -static void dia_unit_spinner_activate(GtkEntry *editable); - static void dia_unit_spinner_class_init(DiaUnitSpinnerClass *class) { - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkEntryClass *editable_class; - - object_class = (GtkObjectClass *)class; - widget_class = (GtkWidgetClass *)class; - editable_class = (GtkEntryClass *)class; - - widget_class->focus_out_event = dia_unit_spinner_focus_out; - widget_class->button_press_event = dia_unit_spinner_button_press; - widget_class->key_press_event = dia_unit_spinner_key_press; - editable_class->activate = dia_unit_spinner_activate; - - parent_class = gtk_type_class(GTK_TYPE_SPIN_BUTTON); - entry_class = gtk_type_class(GTK_TYPE_ENTRY); } static void dia_unit_spinner_init(DiaUnitSpinner *self) { - /* change over to our own print function that appends the unit name on the - * end */ - if (self->parent.adjustment) { - gtk_signal_disconnect_by_data(GTK_OBJECT(self->parent.adjustment), - (gpointer) self); - g_signal_connect(GTK_OBJECT(self->parent.adjustment), "value_changed", - G_CALLBACK(dia_unit_spinner_value_changed), - (gpointer) self); - } - self->unit_num = DIA_UNIT_CENTIMETER; } +/* + Callback functions for the "input" and "output" signals emitted by + GtkSpinButton. All the normal work is done by the spin button, we + simply modify how the text in the GtkEntry is treated. +*/ +static gboolean +dia_unit_spinner_input(DiaUnitSpinner *self, gdouble *value); +static gboolean dia_unit_spinner_output(DiaUnitSpinner *self); + GtkWidget * dia_unit_spinner_new(GtkAdjustment *adjustment, DiaUnit adj_unit) { @@ -1601,14 +1564,17 @@ self->unit_num = adj_unit; - gtk_spin_button_configure(GTK_SPIN_BUTTON(self), adjustment, 0.0, units[adj_unit].digits); + gtk_spin_button_configure(GTK_SPIN_BUTTON(self), + adjustment, 0.0, units[adj_unit].digits); + g_signal_connect(GTK_SPIN_BUTTON(self), "output", + G_CALLBACK(dia_unit_spinner_output), + NULL); + g_signal_connect(GTK_SPIN_BUTTON(self), "input", + G_CALLBACK(dia_unit_spinner_input), + NULL); + if (adjustment) { - gtk_signal_disconnect_by_data(GTK_OBJECT(adjustment), - (gpointer) self); - g_signal_connect(GTK_OBJECT(adjustment), "value_changed", - G_CALLBACK(dia_unit_spinner_value_changed), - (gpointer) self); dia_unit_spinner_set_value(self, adjustment->value); } else { /* Don't know any better, hopefully it'll be set later. */ @@ -1618,42 +1584,9 @@ return GTK_WIDGET(self); } -/** Set the value (in cm). - * */ -void -dia_unit_spinner_set_value(DiaUnitSpinner *self, gfloat val) +static gboolean +dia_unit_spinner_input(DiaUnitSpinner *self, gdouble *value) { - dia_unit_spinner_set_value_direct(self, val / - (units[self->unit_num].factor / units[DIA_UNIT_CENTIMETER].factor)); -} - -/** Set the value (in preferred units) */ -static void -dia_unit_spinner_set_value_direct(DiaUnitSpinner *self, gfloat val) -{ - GtkSpinButton *sbutton = GTK_SPIN_BUTTON(self); - - if (val < sbutton->adjustment->lower) - val = sbutton->adjustment->lower; - else if (val > sbutton->adjustment->upper) - val = sbutton->adjustment->upper; - sbutton->adjustment->value = val; - dia_unit_spinner_value_changed(sbutton->adjustment, self); -} - -/** Get the value (in cm) */ -gfloat -dia_unit_spinner_get_value(DiaUnitSpinner *self) -{ - GtkSpinButton *sbutton = GTK_SPIN_BUTTON(self); - - return sbutton->adjustment->value * - (units[self->unit_num].factor / units[DIA_UNIT_CENTIMETER].factor); -} - -static void -dia_unit_spinner_update(DiaUnitSpinner *self) -{ gfloat val, factor = 1.0; gchar *extra = NULL; @@ -1672,41 +1605,52 @@ } /* convert to prefered units */ val *= factor; - dia_unit_spinner_set_value_direct(self, val); -} -static gint -dia_unit_spinner_focus_out(GtkWidget *widget, GdkEventFocus *event) -{ - if (GTK_ENTRY (widget)->editable) - dia_unit_spinner_update(DIA_UNIT_SPINNER(widget)); - return GTK_WIDGET_CLASS(entry_class)->focus_out_event(widget, event); + /* Store value in the location provided by the signal emitter. */ + *value = val; + + /* Return true, so that the default input function is not invoked. */ + return TRUE; } -static gint -dia_unit_spinner_button_press(GtkWidget *widget, GdkEventButton *event) +static gboolean dia_unit_spinner_output(DiaUnitSpinner *self) { - dia_unit_spinner_update(DIA_UNIT_SPINNER(widget)); - return GTK_WIDGET_CLASS(parent_class)->button_press_event(widget, event); + char buf[256]; + + GtkSpinButton *sbutton = GTK_SPIN_BUTTON(self); + GtkAdjustment *adjustment = gtk_spin_button_get_adjustment(sbutton); + + g_snprintf(buf, sizeof(buf), "%0.*f %s", + gtk_spin_button_get_digits(sbutton), + gtk_adjustment_get_value(adjustment), + units[self->unit_num].unit); + gtk_entry_set_text(GTK_ENTRY(self), buf); + + /* Return true, so that the default output function is not invoked. */ + return TRUE; } -static gint -dia_unit_spinner_key_press(GtkWidget *widget, GdkEventKey *event) +/** Set the value (in cm). + * */ +void +dia_unit_spinner_set_value(DiaUnitSpinner *self, gdouble val) { - gint key = event->keyval; + GtkSpinButton *sbutton = GTK_SPIN_BUTTON(self); - if (GTK_ENTRY (widget)->editable && - (key == GDK_Up || key == GDK_Down || - key == GDK_Page_Up || key == GDK_Page_Down)) - dia_unit_spinner_update (DIA_UNIT_SPINNER(widget)); - return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event); + gtk_spin_button_set_value(sbutton, + val / + (units[self->unit_num].factor / + units[DIA_UNIT_CENTIMETER].factor)); } -static void -dia_unit_spinner_activate(GtkEntry *editable) +/** Get the value (in cm) */ +gdouble +dia_unit_spinner_get_value(DiaUnitSpinner *self) { - if (editable->editable) - dia_unit_spinner_update(DIA_UNIT_SPINNER(editable)); + GtkSpinButton *sbutton = GTK_SPIN_BUTTON(self); + + return gtk_spin_button_get_value(sbutton) * + (units[self->unit_num].factor / units[DIA_UNIT_CENTIMETER].factor); } GList * Index: lib/widgets.h =================================================================== --- lib/widgets.h (revision 3697) +++ lib/widgets.h (working copy) @@ -194,8 +194,8 @@ GtkType dia_unit_spinner_get_type (void); GtkWidget *dia_unit_spinner_new (GtkAdjustment *adjustment, DiaUnit adj_unit); -void dia_unit_spinner_set_value (DiaUnitSpinner *self, gfloat val); -gfloat dia_unit_spinner_get_value (DiaUnitSpinner *self); +void dia_unit_spinner_set_value (DiaUnitSpinner *self, gdouble val); +gdouble dia_unit_spinner_get_value (DiaUnitSpinner *self); GList * get_units_name_list(void); /* DiaDynamicMenu */