#include #include #include #include #include "spinlabeled.h" #define SPIN_LABELED_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPIN_LABELED_TYPE, SpinLabeledPrivate)) #define INT_CUTOFF 0.001 typedef struct _SpinLabeledPrivate SpinLabeledPrivate; struct _SpinLabeledPrivate { gchar *label; gboolean own_string; }; enum { CHANGED_SIGNAL, LAST_SIGNAL }; enum { PROP_0, PROP_LABEL, }; static void spin_labeled_class_init(SpinLabeledClass *); static void spin_labeled_init(SpinLabeled *); static void spin_labeled_get_property(GObject *, guint, GValue *, GParamSpec *); static void spin_labeled_set_property(GObject *, guint, const GValue *, GParamSpec *); static void spin_labeled_render(SpinLabeled *spin_labeled); static guint spin_labeled_signals[LAST_SIGNAL] = { 0 }; GType spin_labeled_get_type() { static GType spin_button_type = 0; if (!spin_button_type) { static const GTypeInfo entry_info = { sizeof (SpinLabeledClass), NULL, NULL, (GClassInitFunc) spin_labeled_class_init, NULL, NULL, sizeof (SpinLabeled), 0, (GInstanceInitFunc) spin_labeled_init, }; spin_button_type = g_type_register_static(GTK_TYPE_SPIN_BUTTON, "SpinLabeled", &entry_info, 0); } return spin_button_type; } static void spin_labeled_class_init(SpinLabeledClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->set_property = spin_labeled_set_property; gobject_class->get_property = spin_labeled_get_property; g_type_class_add_private (klass, sizeof(SpinLabeledPrivate)); spin_labeled_signals[CHANGED_SIGNAL] = g_signal_new("label-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (SpinLabeledClass, label_changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_object_class_install_property(gobject_class, PROP_LABEL, g_param_spec_string("label", "Spin Label", "String to be displayed alongside the number", "", G_PARAM_READWRITE)); } static void spin_labeled_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { SpinLabeled *spin_labeled = SPIN_LABELED(object); SpinLabeledPrivate *priv = SPIN_LABELED_GET_PRIVATE(spin_labeled); switch(prop_id) { case PROP_LABEL: if(priv->own_string) g_free(priv->label); spin_labeled_set_label(spin_labeled, g_value_get_string(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void spin_labeled_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { SpinLabeled *spin_labeled = SPIN_LABELED(object); SpinLabeledPrivate *priv = SPIN_LABELED_GET_PRIVATE(spin_labeled); switch (prop_id) { case PROP_LABEL: if(priv->own_string) g_free(priv->label); priv->label = g_value_dup_string(value); priv->own_string = TRUE; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void spin_labeled_init(SpinLabeled *spin_labeled) { SpinLabeledPrivate *priv = SPIN_LABELED_GET_PRIVATE(spin_labeled); priv->label = ""; priv->own_string = FALSE; } GtkWidget *spin_labeled_new() { return GTK_WIDGET (g_object_new(spin_labeled_get_type(), NULL)); } gchar *spin_labeled_get_label(SpinLabeled *spin_labeled) { SpinLabeledPrivate *priv = SPIN_LABELED_GET_PRIVATE(spin_labeled); return priv->label; } void spin_labeled_set_label(SpinLabeled *spin_labeled, const gchar *new_label) { gchar *buf; SpinLabeledPrivate *priv = SPIN_LABELED_GET_PRIVATE(spin_labeled); if(priv->own_string) g_free(priv->label); buf = g_malloc0(strlen(new_label) + 1); strcpy(buf, new_label); priv->label = buf; priv->own_string = TRUE; spin_labeled_render(spin_labeled); g_signal_emit_by_name((gpointer) spin_labeled, "label-changed"); } static void spin_labeled_render(SpinLabeled *spin_labeled) { SpinLabeledPrivate *priv = SPIN_LABELED_GET_PRIVATE(spin_labeled); GString *text; gboolean is_int; double dbl; gint n; text = g_string_new(NULL); dbl = gtk_spin_button_get_value(GTK_SPIN_BUTTON (spin_labeled)); is_int = (fabs(rint(dbl) - dbl) < INT_CUTOFF); if(is_int) { n = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON (spin_labeled)); g_string_append_printf(text, "%d %s", n, priv->label); } else { g_string_append_printf(text, "%f %s", dbl, priv->label); } gtk_entry_set_text(GTK_ENTRY (spin_labeled), text->str); g_string_free(text, TRUE); }