[glade] Fix issue with numeric property editors. We have to make sure glade_eprop_numeric_load() is not cal
- From: Juan Pablo Ugarte <jpu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade] Fix issue with numeric property editors. We have to make sure glade_eprop_numeric_load() is not cal
- Date: Mon, 25 Nov 2013 19:42:24 +0000 (UTC)
commit 59517e20188145c7e5f0440bdd549199e3331cdb
Author: Juan Pablo Ugarte <juanpablougarte gmail com>
Date: Mon Nov 25 16:27:08 2013 -0300
Fix issue with numeric property editors.
We have to make sure glade_eprop_numeric_load() is not called during
glade_eprop_numeric_force_update() to prevent gtk_spin_button_set_value()
changing the the value the user is trying to input.
gladeui/glade-editor-property.c | 133 +++++++++++++++++++++++++-------------
1 files changed, 87 insertions(+), 46 deletions(-)
---
diff --git a/gladeui/glade-editor-property.c b/gladeui/glade-editor-property.c
index 8784450..0f5f730 100644
--- a/gladeui/glade-editor-property.c
+++ b/gladeui/glade-editor-property.c
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <string.h>
+#include <math.h>
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
@@ -703,6 +704,8 @@ typedef struct
GladeEditorProperty parent_instance;
GtkWidget *spin;
+
+ gboolean refreshing;
} GladeEPropNumeric;
GLADE_MAKE_EPROP (GladeEPropNumeric, glade_eprop_numeric)
@@ -711,7 +714,8 @@ GLADE_MAKE_EPROP (GladeEPropNumeric, glade_eprop_numeric)
#define GLADE_IS_EPROP_NUMERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EPROP_NUMERIC))
#define GLADE_IS_EPROP_NUMERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EPROP_NUMERIC))
#define GLADE_EPROP_NUMERIC_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GLADE_EPROP_NUMERIC,
GladeEPropNumericClass))
- static void glade_eprop_numeric_finalize (GObject *object)
+static void
+glade_eprop_numeric_finalize (GObject *object)
{
/* Chain up */
G_OBJECT_CLASS (editor_property_class)->finalize (object);
@@ -720,11 +724,14 @@ GLADE_MAKE_EPROP (GladeEPropNumeric, glade_eprop_numeric)
static void
glade_eprop_numeric_load (GladeEditorProperty *eprop, GladeProperty *property)
{
- gfloat val = 0.0F;
+ gdouble val = 0.0F;
GladeEPropNumeric *eprop_numeric = GLADE_EPROP_NUMERIC (eprop);
GParamSpec *pspec;
GValue *value;
+ if (eprop_numeric->refreshing)
+ return;
+
/* Chain up first */
editor_property_class->load (eprop, property);
@@ -734,19 +741,19 @@ glade_eprop_numeric_load (GladeEditorProperty *eprop, GladeProperty *property)
pspec = glade_property_class_get_pspec (eprop->priv->klass);
if (G_IS_PARAM_SPEC_INT (pspec))
- val = (gfloat) g_value_get_int (value);
+ val = g_value_get_int (value);
else if (G_IS_PARAM_SPEC_UINT (pspec))
- val = (gfloat) g_value_get_uint (value);
+ val = g_value_get_uint (value);
else if (G_IS_PARAM_SPEC_LONG (pspec))
- val = (gfloat) g_value_get_long (value);
+ val = g_value_get_long (value);
else if (G_IS_PARAM_SPEC_ULONG (pspec))
- val = (gfloat) g_value_get_ulong (value);
+ val = g_value_get_ulong (value);
else if (G_IS_PARAM_SPEC_INT64 (pspec))
- val = (gfloat) g_value_get_int64 (value);
+ val = g_value_get_int64 (value);
else if (G_IS_PARAM_SPEC_UINT64 (pspec))
- val = (gfloat) g_value_get_uint64 (value);
+ val = g_value_get_uint64 (value);
else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
- val = (gfloat) g_value_get_double (value);
+ val = g_value_get_double (value);
else if (G_IS_PARAM_SPEC_FLOAT (pspec))
val = g_value_get_float (value);
else
@@ -756,6 +763,30 @@ glade_eprop_numeric_load (GladeEditorProperty *eprop, GladeProperty *property)
}
}
+#define NEAREST_INT_CAST(x) (((x - floor (x) < ceil (x) - x)) ? floor (x) : ceil (x))
+
+static void
+glade_eprop_numeric_value_set (GValue *val, gdouble value)
+{
+ if (G_VALUE_HOLDS_INT (val))
+ g_value_set_int (val, NEAREST_INT_CAST (value));
+ else if (G_VALUE_HOLDS_UINT (val))
+ g_value_set_uint (val, NEAREST_INT_CAST (value));
+ else if (G_VALUE_HOLDS_LONG (val))
+ g_value_set_long (val, NEAREST_INT_CAST (value));
+ else if (G_VALUE_HOLDS_ULONG (val))
+ g_value_set_ulong (val, NEAREST_INT_CAST (value));
+ else if (G_VALUE_HOLDS_INT64 (val))
+ g_value_set_int64 (val, NEAREST_INT_CAST (value));
+ else if (G_VALUE_HOLDS_UINT64 (val))
+ g_value_set_uint64 (val, NEAREST_INT_CAST (value));
+ else if (G_VALUE_HOLDS_FLOAT (val))
+ g_value_set_float (val, value);
+ else if (G_VALUE_HOLDS_DOUBLE (val))
+ g_value_set_double (val, value);
+ else
+ g_warning ("Unsupported type %s\n", G_VALUE_TYPE_NAME (val));
+}
static void
glade_eprop_numeric_changed (GtkWidget *spin, GladeEditorProperty *eprop)
@@ -768,34 +799,7 @@ glade_eprop_numeric_changed (GtkWidget *spin, GladeEditorProperty *eprop)
pspec = glade_property_class_get_pspec (eprop->priv->klass);
g_value_init (&val, pspec->value_type);
-
- if (G_IS_PARAM_SPEC_INT (pspec))
- g_value_set_int (&val, gtk_spin_button_get_value_as_int
- (GTK_SPIN_BUTTON (spin)));
- else if (G_IS_PARAM_SPEC_UINT (pspec))
- g_value_set_uint (&val, gtk_spin_button_get_value_as_int
- (GTK_SPIN_BUTTON (spin)));
- else if (G_IS_PARAM_SPEC_LONG (pspec))
- g_value_set_long (&val, (glong) gtk_spin_button_get_value_as_int
- (GTK_SPIN_BUTTON (spin)));
- else if (G_IS_PARAM_SPEC_ULONG (pspec))
- g_value_set_ulong (&val, (gulong) gtk_spin_button_get_value_as_int
- (GTK_SPIN_BUTTON (spin)));
- else if (G_IS_PARAM_SPEC_INT64 (pspec))
- g_value_set_int64 (&val, (gint64) gtk_spin_button_get_value_as_int
- (GTK_SPIN_BUTTON (spin)));
- else if (G_IS_PARAM_SPEC_UINT64 (pspec))
- g_value_set_uint64 (&val, (guint64) gtk_spin_button_get_value_as_int
- (GTK_SPIN_BUTTON (spin)));
- else if (G_IS_PARAM_SPEC_FLOAT (pspec))
- g_value_set_float (&val, (gfloat) gtk_spin_button_get_value
- (GTK_SPIN_BUTTON (spin)));
- else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
- g_value_set_double (&val, gtk_spin_button_get_value
- (GTK_SPIN_BUTTON (spin)));
- else
- g_warning ("Unsupported type %s\n",
- g_type_name (G_PARAM_SPEC_TYPE (pspec)));
+ glade_eprop_numeric_value_set (&val, gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin)));
glade_editor_property_commit_no_callback (eprop, &val);
g_value_unset (&val);
@@ -805,21 +809,55 @@ static void
glade_eprop_numeric_force_update (GtkSpinButton *spin,
GladeEditorProperty *eprop)
{
- const gchar *txt;
+ GladeProperty *prop = glade_editor_property_get_property (eprop);
+ GladePropertyClass *klass = glade_property_get_class (prop);
+ GValue *val, newval = G_VALUE_INIT;
+ gdouble value;
+ gchar *text;
- txt = gtk_entry_get_text (GTK_ENTRY (spin));
+ val = glade_property_inline_value (prop);
+ text = gtk_editable_get_chars (GTK_EDITABLE (spin), 0, -1);
- /* Here we only force an update if there is actually text
- * to force an update with.
- *
+ g_value_init (&newval, G_VALUE_TYPE (val));
+ value = g_strtod (text, NULL);
+ glade_eprop_numeric_value_set (&newval, value);
+
+ /*
* If we unconditionally update the spin button whenever
* the entry changes we get bogus results (notably, the
* updating the spin button will insert 0 whenever text
* is removed, so selecting and inserting text will have
* an appended 0).
- */
- if (txt && txt[0])
- gtk_spin_button_update (spin);
+ */
+ if (glade_property_class_compare (klass, val, &newval))
+ {
+ gdouble min, max;
+
+ gtk_spin_button_get_range (spin, &min, &max);
+
+ if (value < min || value > max)
+ {
+ /* Special case, if the value is out of range, we force an update to
+ * change the value in the spin so the user knows about the range issue.
+ */
+ gtk_spin_button_update (spin);
+ }
+ else
+ {
+ /* Here we commit the new property value but we make sure
+ * glade_eprop_numeric_load() is not called to prevent
+ * gtk_spin_button_set_value() changing the the value the
+ * user is trying to input.
+ */
+ GladeEPropNumeric *eprop_numeric = GLADE_EPROP_NUMERIC (eprop);
+ eprop_numeric->refreshing = TRUE;
+ glade_editor_property_commit_no_callback (eprop, &newval);
+ eprop_numeric->refreshing = FALSE;
+ }
+ }
+
+ g_value_unset (&newval);
+ g_free (text);
}
static GtkWidget *
@@ -851,11 +889,14 @@ glade_eprop_numeric_create_input (GladeEditorProperty *eprop)
/* The force update callback is here to ensure that whenever the value
* is modified, it's committed immediately without requiring entry activation
* (this avoids lost modifications when modifying a value and navigating away)
+ *
+ * FIXME: GtkSpinButton update its value on focus-out, why is not that enough?
+ * Could it be because this callback was used before using spins?
*/
g_signal_connect (G_OBJECT (eprop_numeric->spin), "changed",
G_CALLBACK (glade_eprop_numeric_force_update), eprop);
- g_signal_connect (G_OBJECT (eprop_numeric->spin), "value_changed",
+ g_signal_connect (G_OBJECT (eprop_numeric->spin), "value-changed",
G_CALLBACK (glade_eprop_numeric_changed), eprop);
return eprop_numeric->spin;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]