/* * Copyright (C) 2012 - Juan Ferrer Toribio * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "vn-spin.h" #include /** * SECTION:vn-spin * @Short_description: an incrementable numeric field * @Title: VnSpin * @See_also: #VnField * @Image: spin.png * * An incrementable numeric field */ G_DEFINE_TYPE (VnSpin, vn_spin, VN_TYPE_FIELD); /** * vn_spin_new: * * Creates a new #VnSpin * * Return value: a #VnSpin **/ VnField * vn_spin_new () { return g_object_new (VN_TYPE_SPIN, NULL); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private static void vn_spin_on_value_changed (GtkSpinButton * spin, VnField * self) { GValue value = G_VALUE_INIT; if (g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (spin)), "")) { g_value_init (&value, G_TYPE_DOUBLE); g_value_set_double (&value, gtk_spin_button_get_value (spin)); } else g_value_init (&value, GVN_TYPE_NULL); VN_FIELD_GET_CLASS (self)->value_changed (self, &value); g_value_unset (&value); } static gboolean vn_spin_on_focus_out (GtkSpinButton * spin, GdkEvent * event, VnField * self) { vn_spin_on_value_changed (spin, self); return FALSE; } static gboolean vn_spin_on_output (GtkSpinButton * spin, VnField * self) { const gchar * text = gtk_entry_get_text (GTK_ENTRY (spin)); return !text || !g_strcmp0 (text, ""); } static void vn_spin_set_value (VnSpin * self, const GValue * value) { g_signal_handlers_block_by_func (self->spin, vn_spin_on_value_changed, self); if (!gvn_value_is_null (value)) { GValue new_value = {0}; g_value_init (&new_value, G_TYPE_DOUBLE); g_value_transform (value, &new_value); g_signal_handlers_block_by_func (self->spin, vn_spin_on_output, self); gtk_spin_button_set_value (self->spin, g_value_get_double (&new_value)); g_signal_handlers_unblock_by_func (self->spin, vn_spin_on_output, self); g_value_unset (&new_value); } else gtk_entry_set_text (GTK_ENTRY (self->spin), ""); g_signal_handlers_unblock_by_func (self->spin, vn_spin_on_value_changed, self); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties enum { PROP_DIGITS = 1 }; static void vn_spin_set_property (VnSpin * self, guint id, const GValue * value, GParamSpec * pspec) { switch (id) { case PROP_DIGITS: gtk_spin_button_set_digits (self->spin, g_value_get_uint (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec); } } static void vn_spin_get_property (VnSpin * self, guint id, GValue * value, GParamSpec * pspec) { switch (id) { case PROP_DIGITS: g_value_set_uint (value, gtk_spin_button_get_digits (self->spin)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, id, pspec); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void vn_spin_init (VnSpin * self) { self->spin = GTK_SPIN_BUTTON (gtk_spin_button_new (NULL, 1, 0)); gtk_spin_button_set_range (self->spin, G_MININT, G_MAXINT); gtk_spin_button_set_update_policy (self->spin, GTK_UPDATE_ALWAYS); gtk_spin_button_set_numeric (self->spin, TRUE); gtk_spin_button_set_increments (self->spin, 1, 1); gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->spin)); g_object_connect (self->spin // ,"signal::activate", vn_spin_on_value_changed, self ,"signal::value-changed", vn_spin_on_value_changed, self ,"signal::focus-out-event", vn_spin_on_focus_out, self ,"signal::output", vn_spin_on_output, self ,NULL ); g_signal_connect (self->spin, "value-changed", G_CALLBACK (vn_spin_on_value_changed), self); g_signal_connect (self->spin, "output", G_CALLBACK (vn_spin_on_output), self); VN_FIELD_GET_CLASS (self)->set_widget (VN_FIELD (self), GTK_WIDGET (self->spin)); } static void vn_spin_finalize (VnSpin * self) { G_OBJECT_CLASS (vn_spin_parent_class)->finalize (G_OBJECT (self)); } static void vn_spin_class_init (VnSpinClass * klass) { GObjectClass * k = G_OBJECT_CLASS (klass); k->set_property = (GObjectSetPropertyFunc) vn_spin_set_property; k->get_property = (GObjectGetPropertyFunc) vn_spin_get_property; G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) vn_spin_finalize; VN_FIELD_CLASS (klass)->set_value = (VnFieldSetValueFunc) vn_spin_set_value; g_object_class_install_property (k, PROP_DIGITS, g_param_spec_uint ("digits" ,_("Digits") ,_("The number of decimal places to display.") ,0 ,20 ,0 ,G_PARAM_CONSTRUCT | G_PARAM_READWRITE )); }