[gtk] scale: Replace format-value signal



commit ea5fc348fa6143bcd9a1979db2734617de01c96c
Author: Timm Bäder <mail baedert org>
Date:   Fri Aug 9 13:32:24 2019 +0200

    scale: Replace format-value signal
    
    There is no reason for this to be a signal, since multiple handlers
    don't make sense anyway. It was also broken because the scale needs to
    know when a signal handler is added so it can update the value
    representation.
    
    Replace the signal with a set_format_value_func function which allows us
    to do that.
    
    Fixes #113

 demos/widget-factory/widget-factory.c  |  16 +++--
 demos/widget-factory/widget-factory.ui |   2 -
 gtk/gtkscale.c                         | 108 ++++++++++++++++-----------------
 gtk/gtkscale.h                         |  22 ++++++-
 4 files changed, 80 insertions(+), 68 deletions(-)
---
diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c
index 24dfa14f2a..50bcc8c600 100644
--- a/demos/widget-factory/widget-factory.c
+++ b/demos/widget-factory/widget-factory.c
@@ -1603,14 +1603,14 @@ reset_icon_size (GtkWidget *iv)
   gtk_widget_queue_resize (iv);
 }
 
-static gchar *
-scale_format_value_blank (GtkScale *scale, gdouble value)
+static char *
+scale_format_value_blank (GtkScale *scale, double value, gpointer user_data)
 {
   return g_strdup (" ");
 }
 
-static gchar *
-scale_format_value (GtkScale *scale, gdouble value)
+static char *
+scale_format_value (GtkScale *scale, double value, gpointer user_data)
 {
   return g_strdup_printf ("%0.*f", 1, value);
 }
@@ -1724,8 +1724,6 @@ activate (GApplication *app)
   gtk_builder_add_callback_symbol (builder, "increase_icon_size", (GCallback)increase_icon_size);
   gtk_builder_add_callback_symbol (builder, "decrease_icon_size", (GCallback)decrease_icon_size);
   gtk_builder_add_callback_symbol (builder, "reset_icon_size", (GCallback)reset_icon_size);
-  gtk_builder_add_callback_symbol (builder, "scale_format_value", (GCallback)scale_format_value);
-  gtk_builder_add_callback_symbol (builder, "scale_format_value_blank", (GCallback)scale_format_value_blank);
   gtk_builder_add_callback_symbol (builder, "osd_frame_pressed", (GCallback)osd_frame_pressed);
 
   gtk_builder_connect_signals (builder, NULL);
@@ -1945,6 +1943,12 @@ activate (GApplication *app)
   widget = (GtkWidget *)gtk_builder_get_object (builder, "extra_info_entry");
   g_timeout_add (100, (GSourceFunc)pulse_it, widget);
 
+  widget = (GtkWidget *)gtk_builder_get_object (builder, "scale3");
+  gtk_scale_set_format_value_func (GTK_SCALE (widget), scale_format_value, NULL);
+
+  widget = (GtkWidget *)gtk_builder_get_object (builder, "scale4");
+  gtk_scale_set_format_value_func (GTK_SCALE (widget), scale_format_value_blank, NULL);
+
   widget = (GtkWidget *)gtk_builder_get_object (builder, "box_for_context");
   model = (GMenuModel *)gtk_builder_get_object (builder, "new_style_context_menu_model");
   set_up_context_popover (widget, model);
diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui
index c861a6f475..09639bda56 100644
--- a/demos/widget-factory/widget-factory.ui
+++ b/demos/widget-factory/widget-factory.ui
@@ -1019,7 +1019,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
                                         <property name="fill-level">75</property>
                                         <property name="digits">-1</property>
                                         <property name="halign">end</property>
-                                        <signal name="format-value" handler="scale_format_value"/>
                                       </object>
                                     </child>
                                     <child>
@@ -1033,7 +1032,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
                                         <property name="fill-level">75</property>
                                         <property name="digits">-1</property>
                                         <property name="halign">start</property>
-                                        <signal name="format-value" handler="scale_format_value_blank"/>
                                       </object>
                                     </child>
                                   </object>
diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c
index ba5b2d2130..7f8aa1e071 100644
--- a/gtk/gtkscale.c
+++ b/gtk/gtkscale.c
@@ -148,6 +148,9 @@ struct _GtkScalePrivate
 
   gint          digits;
 
+  GtkScaleFormatValueFunc format_value_func;
+  gpointer format_value_func_user_data;
+
   guint         draw_value : 1;
   guint         value_pos  : 2;
 };
@@ -172,13 +175,8 @@ enum {
   LAST_PROP
 };
 
-enum {
-  FORMAT_VALUE,
-  LAST_SIGNAL
-};
 
 static GParamSpec *properties[LAST_PROP];
-static guint signals[LAST_SIGNAL];
 
 static void     gtk_scale_set_property            (GObject        *object,
                                                    guint           prop_id,
@@ -264,7 +262,6 @@ update_label_request (GtkScale *scale)
   size = MAX (size, min);
   g_free (text);
 
-
   text = gtk_scale_format_value (scale, highest_value);
   gtk_label_set_label (GTK_LABEL (priv->value_widget), text);
 
@@ -665,42 +662,6 @@ gtk_scale_class_init (GtkScaleClass *class)
 
   class->get_layout_offsets = gtk_scale_real_get_layout_offsets;
 
-  /**
-   * GtkScale::format-value:
-   * @scale: the object which received the signal
-   * @value: the value to format
-   *
-   * Signal which allows you to change how the scale value is displayed.
-   * Connect a signal handler which returns an allocated string representing 
-   * @value. That string will then be used to display the scale's value.
-   *
-   * If no user-provided handlers are installed, the value will be displayed on
-   * its own, rounded according to the value of the #GtkScale:digits property.
-   *
-   * Here's an example signal handler which displays a value 1.0 as
-   * with "-->1.0<--".
-   * |[<!-- language="C" -->
-   * static gchar*
-   * format_value_callback (GtkScale *scale,
-   *                        gdouble   value)
-   * {
-   *   return g_strdup_printf ("-->\%0.*g<--",
-   *                           gtk_scale_get_digits (scale), value);
-   *  }
-   * ]|
-   *
-   * Returns: allocated string representing @value
-   */
-  signals[FORMAT_VALUE] =
-    g_signal_new (I_("format-value"),
-                  G_TYPE_FROM_CLASS (gobject_class),
-                  G_SIGNAL_RUN_LAST,
-                  G_STRUCT_OFFSET (GtkScaleClass, format_value),
-                  _gtk_single_string_accumulator, NULL,
-                  _gtk_marshal_STRING__DOUBLE,
-                  G_TYPE_STRING, 1,
-                  G_TYPE_DOUBLE);
-
   properties[PROP_DIGITS] =
       g_param_spec_int ("digits",
                         P_("Digits"),
@@ -1023,7 +984,7 @@ gtk_scale_new_with_range (GtkOrientation orientation,
  *
  * Note that rounding to a small number of digits can interfere with
  * the smooth autoscrolling that is built into #GtkScale. As an alternative,
- * you can use the #GtkScale::format-value signal to format the displayed
+ * you can use gtk_scale_set_format_value_func() to format the displayed
  * value yourself.
  */
 void
@@ -1560,26 +1521,19 @@ weed_out_neg_zero (gchar *str,
   return str;
 }
 
-/*
- * Emits #GtkScale:format-value signal to format the value;
- * if no user signal handlers, falls back to a default format.
- *
- * Returns: formatted value
- */
-static gchar *
+static char *
 gtk_scale_format_value (GtkScale *scale,
-                        gdouble   value)
+                        double    value)
 {
-  gchar *fmt = NULL;
   GtkScalePrivate *priv = gtk_scale_get_instance_private (scale);
 
-  g_signal_emit (scale, signals[FORMAT_VALUE], 0, value, &fmt);
-
-  if (fmt)
-    return fmt;
+  if (priv->format_value_func)
+    {
+      return priv->format_value_func (scale, value, priv->format_value_func_user_data);
+    }
   else
     {
-      fmt = g_strdup_printf ("%0.*f", priv->digits, value);
+      char *fmt = g_strdup_printf ("%0.*f", priv->digits, value);
       return weed_out_neg_zero (fmt, priv->digits);
     }
 }
@@ -2075,3 +2029,43 @@ gtk_scale_buildable_custom_finished (GtkBuildable *buildable,
     }
 
 }
+
+/**
+ * gtk_scale_set_format_value_func:
+ * @scale: a #GtkScale
+ * @func: (nullable): function that formats the value
+ * @user_data: (nullable): user data to pass to @func
+ *
+ * @func allows you to change how the scale value is displayed. The given
+ * function will return an allocated string representing @value.
+ * That string will then be used to display the scale's value.
+ *
+ * If #NULL is passed as @func, the value will be displayed on
+ * its own, rounded according to the value of the #GtkScale:digits property.
+ */
+void
+gtk_scale_set_format_value_func (GtkScale                *scale,
+                                 GtkScaleFormatValueFunc  func,
+                                 gpointer                 user_data)
+{
+  GtkScalePrivate *priv = gtk_scale_get_instance_private (scale);
+  GtkAdjustment *adjustment;
+  char *text;
+
+  g_return_if_fail (GTK_IS_SCALE (scale));
+
+  priv->format_value_func = func;
+  priv->format_value_func_user_data = user_data;
+
+  if (!priv->value_widget)
+    return;
+
+  update_label_request (scale);
+
+  adjustment = gtk_range_get_adjustment (GTK_RANGE (scale));
+  text = gtk_scale_format_value (scale,
+                                 gtk_adjustment_get_value (adjustment));
+  gtk_label_set_label (GTK_LABEL (priv->value_widget), text);
+
+  g_free (text);
+}
diff --git a/gtk/gtkscale.h b/gtk/gtkscale.h
index a76cd81f53..c18a82ecff 100644
--- a/gtk/gtkscale.h
+++ b/gtk/gtkscale.h
@@ -55,9 +55,6 @@ struct _GtkScaleClass
 {
   GtkRangeClass parent_class;
 
-  gchar* (* format_value) (GtkScale *scale,
-                           gdouble   value);
-
   void (* get_layout_offsets) (GtkScale *scale,
                                gint     *x,
                                gint     *y);
@@ -67,6 +64,21 @@ struct _GtkScaleClass
   gpointer padding[8];
 };
 
+
+/**
+ * GtkScaleFormatValueFunc:
+ * @scale: The #GtkScale
+ * @value: The numeric value to format
+ * @user_data: (closure): user data
+ *
+ * Returns: (not nullable): A newly allocated string describing a textual representation
+ *   of the given numerical value.
+ */
+typedef char * (*GtkScaleFormatValueFunc) (GtkScale *scale,
+                                           double    value,
+                                           gpointer  user_data);
+
+
 GDK_AVAILABLE_IN_ALL
 GType             gtk_scale_get_type           (void) G_GNUC_CONST;
 GDK_AVAILABLE_IN_ALL
@@ -113,6 +125,10 @@ void              gtk_scale_add_mark           (GtkScale        *scale,
 GDK_AVAILABLE_IN_ALL
 void              gtk_scale_clear_marks        (GtkScale        *scale);
 
+GDK_AVAILABLE_IN_ALL
+void              gtk_scale_set_format_value_func (GtkScale                *scale,
+                                                   GtkScaleFormatValueFunc  func,
+                                                   gpointer                 user_data);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]