[prev in list] [next in list] [prev in thread] [next in thread] 

List:       dia-list
Subject:    Re: new improved DiaUnitSpinner
From:       "Sameer Sahasrabuddhe" <sameerds () gmail ! com>
Date:       2007-06-13 10:13:39
Message-ID: 4cc31ad30706130301p1abf84f9ndb38991f2fef86c5 () mail ! gmail ! com
[Download RAW message or body]

Hello,

Attaching a new patch that obsoletes the one I posted earlier. I
decided I could clean it up a bit further and also make it strictly
Gtk+ 2.0 ... sorry about the premature posting!

Sameer.

On 6/13/07, Sameer Sahasrabuddhe <sameerds@gmail.com> wrote:
> Hello,
>
> I have a patch ready that introduces signals in all the custom widgets
> used for setting properties for objects or groups. But I have isolated
> one widget that needed major rework --- DiaUnitSpinner --- mostly
> removing all the customised code and using Gtk+ 2.0 facilities
> instead.
>
> Attaching a patch.
>
> Sameer.
> --
> Research Scholar, KReSIT, IIT Bombay
> http://www.it.iitb.ac.in/~sameerds/
>
>


-- 
Research Scholar, KReSIT, IIT Bombay
http://www.it.iitb.ac.in/~sameerds/

["unit_spinner_clean.patch" (text/x-patch)]

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 */


_______________________________________________
Dia-list mailing list
Dia-list@gnome.org
http://mail.gnome.org/mailman/listinfo/dia-list
FAQ at http://live.gnome.org/Dia/Faq
Main page at http://live.gnome.org/Dia



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic