Index: lib/widgets.c =================================================================== --- lib/widgets.c (revision 3697) +++ lib/widgets.c (working copy) @@ -1512,148 +1512,83 @@ { 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); -GtkType +GType dia_unit_spinner_get_type(void) { - static GtkType us_type = 0; + static GType us_type = 0; if (!us_type) { - static const GtkTypeInfo us_info = { - "DiaUnitSpinner", - sizeof(DiaUnitSpinner), + static const GTypeInfo us_info = { sizeof(DiaUnitSpinnerClass), - (GtkClassInitFunc) dia_unit_spinner_class_init, - (GtkObjectInitFunc) dia_unit_spinner_init, - NULL, - NULL, - (GtkClassInitFunc) NULL, + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, /* class_init*/ + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(DiaUnitSpinner), + 0, /* n_preallocs */ + (GInstanceInitFunc) dia_unit_spinner_init, }; - us_type = gtk_type_unique(gtk_spin_button_get_type(), &us_info); + us_type = g_type_register_static(GTK_TYPE_SPIN_BUTTON, + "DiaUnitSpinner", + &us_info, 0); } 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; + /* + _configure called in _new assumes that if no adjustment is passed, + the widget already has one. Hence this must be set here. This + behaviour is identical to GtkSpinButton, although the default + adjustment is pretty useless. + */ + gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(self), + (GtkAdjustment*) + gtk_adjustment_new (0, 0, 0, 0, 0, 0)); } +/* + 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) { - DiaUnitSpinner *self = gtk_type_new(dia_unit_spinner_get_type()); - + DiaUnitSpinner *self; + if (adjustment) + g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), NULL); + + self = gtk_type_new(dia_unit_spinner_get_type()); 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. */ - dia_unit_spinner_set_value(self, 1.0); - } - 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 +1607,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 */