]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtklevelbar.c
filechooserbutton: Emit 'selection-changed' when changing the selection programmatically
[~andy/gtk] / gtk / gtklevelbar.c
index 4a371042e5fb494f92c3d9203478547494fd79a1..fff48919e8763c85d112b4b67d9a57ee9cdfdde3 100644 (file)
  * @Short_description: A bar that can used as a level indicator
  *
  * The #GtkLevelBar is a bar widget that can be used
- * as a level indicator. Typical use cases are displaying the level
+ * as a level indicator. Typical use cases are displaying the strength
  * of a password, or showing the charge level of a battery.
  *
- * Use #gtk_level_bar_set_value to set the current value, and
- * #gtk_level_bar_add_offset_value to set the value offsets at which 
+ * Use gtk_level_bar_set_value() to set the current value, and
+ * gtk_level_bar_add_offset_value() to set the value offsets at which
  * the bar will be considered in a different state. GTK will add two offsets
  * by default on the level bar: #GTK_LEVEL_BAR_OFFSET_LOW and
  * #GTK_LEVEL_BAR_OFFSET_HIGH, with values 0.25 and 0.75 respectively.
  *
+ * <example>
+ * <title>Adding a custom offset on the bar</title>
+ * <programlisting>
+ *
+ * static GtkWidget *
+ * create_level_bar (void)
+ * {
+ *   GtkWidget *level_bar;
+ *
+ *   level_bar = gtk_level_bar_new ();
+ *
+ *   /<!---->* This changes the value of the default low offset *<!---->/
+ *   gtk_level_bar_add_offset_value (GTK_LEVEL_BAR (level_bar),
+ *                                   GTK_LEVEL_BAR_OFFSET_LOW, 0.10);
+ *
+ *   /<!---->* This adds a new offset to the bar; the application will
+ *    * be able to change its color by using the following selector,
+ *    * either by adding it to its CSS file or using
+ *    * gtk_css_provider_load_from_data() and gtk_style_context_add_provider()
+ *    *
+ *    * .level-bar.fill-block.level-my-offset {
+ *    *   background-color: green;
+ *    *   border-style: solid;
+ *    *   border-color: black;
+ *    *   border-style: 1px;
+ *    * }
+ *    *<!---->/
+ *   gtk_level_bar_add_offset_value (GTK_LEVEL_BAR (level_bar),
+ *                                   "my-offset", 0.60);
+ *
+ *   return level_bar;
+ * }
+ * </programlisting>
+ * </example>
+ *
  * The default interval of values is between zero and one, but it's possible to
- * modify the interval using #gtk_level_bar_set_min_value and
- * #gtk_level_bar_set_max_value. The value will be always drawn in proportion to
+ * modify the interval using gtk_level_bar_set_min_value() and
+ * gtk_level_bar_set_max_value(). The value will be always drawn in proportion to
  * the admissible interval, i.e. a value of 15 with a specified interval between
  * 10 and 20 is equivalent to a value of 0.5 with an interval between 0 and 1.
  * When #GTK_LEVEL_BAR_MODE_DISCRETE is used, the bar level is rendered
 #include <math.h>
 #include <stdlib.h>
 
+#include "a11y/gtklevelbaraccessible.h"
+
+#include "fallback-c89.c"
+
 #define DEFAULT_BLOCK_SIZE 3
 
 /* these don't make sense outside of GtkLevelBar, so we don't add
@@ -83,6 +122,7 @@ enum {
   PROP_MIN_VALUE,
   PROP_MAX_VALUE,
   PROP_MODE,
+  PROP_INVERTED,
   LAST_PROPERTY,
   PROP_ORIENTATION /* overridden */
 };
@@ -110,10 +150,12 @@ struct _GtkLevelBarPrivate {
   GList *offsets;
 
   GtkLevelBarMode bar_mode;
+
+  guint inverted : 1;
 };
 
-static void gtk_level_bar_set_value_internal          (GtkLevelBar *self,
-                                                       gdouble      value);
+static void gtk_level_bar_set_value_internal (GtkLevelBar *self,
+                                              gdouble      value);
 
 static GtkLevelBarOffset *
 gtk_level_bar_offset_new (const gchar *name,
@@ -165,7 +207,7 @@ gtk_level_bar_ensure_offset (GtkLevelBar *self,
   existing = g_list_find_custom (self->priv->offsets, name, offset_find_func);
   if (existing)
     offset = existing->data;
+
   if (offset && (offset->value == value))
     return FALSE;
 
@@ -266,6 +308,7 @@ gtk_level_bar_get_borders (GtkLevelBar *self,
 static void
 gtk_level_bar_draw_fill_continuous (GtkLevelBar           *self,
                                     cairo_t               *cr,
+                                    gboolean               inverted,
                                     cairo_rectangle_int_t *fill_area)
 {
   GtkWidget *widget = GTK_WIDGET (self);
@@ -293,6 +336,8 @@ gtk_level_bar_draw_fill_continuous (GtkLevelBar           *self,
   gtk_render_frame (context, cr, base_area.x, base_area.y,
                     base_area.width, base_area.height);
 
+  gtk_style_context_remove_class (context, STYLE_CLASS_EMPTY_FILL_BLOCK);
+
   /* now render the filled part on top of it */
   block_area = base_area;
 
@@ -300,11 +345,19 @@ gtk_level_bar_draw_fill_continuous (GtkLevelBar           *self,
     (self->priv->max_value - self->priv->min_value);
 
   if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-    block_area.width = (gint) floor (block_area.width * fill_percentage);
+    {
+      block_area.width = (gint) floor (block_area.width * fill_percentage);
+
+      if (inverted)
+        block_area.x += base_area.width - block_area.width;
+    }
   else
-    block_area.height = (gint) floor (block_area.height * fill_percentage);
+    {
+      block_area.height = (gint) floor (block_area.height * fill_percentage);
 
-  gtk_style_context_remove_class (context, STYLE_CLASS_EMPTY_FILL_BLOCK);
+      if (inverted)
+        block_area.y += base_area.height - block_area.height;
+    }
 
   gtk_render_background (context, cr, block_area.x, block_area.y,
                          block_area.width, block_area.height);
@@ -317,6 +370,7 @@ gtk_level_bar_draw_fill_continuous (GtkLevelBar           *self,
 static void
 gtk_level_bar_draw_fill_discrete (GtkLevelBar           *self,
                                   cairo_t               *cr,
+                                  gboolean               inverted,
                                   cairo_rectangle_int_t *fill_area)
 {
   GtkWidget *widget = GTK_WIDGET (self);
@@ -350,19 +404,35 @@ gtk_level_bar_draw_fill_discrete (GtkLevelBar           *self,
     {
       block_draw_height = MAX (block_draw_height, block_area.height - block_margin.top - block_margin.bottom);
       block_area.y += block_margin.top;
+
+      if (inverted)
+        block_area.x += block_area.width - block_draw_width;
     }
   else
     {
       block_draw_width = MAX (block_draw_width, block_area.width - block_margin.left - block_margin.right);
       block_area.x += block_margin.left;
+
+      if (inverted)
+        block_area.y += block_area.height - block_draw_height;
     }
 
   for (idx = 0; idx < num_blocks; idx++)
     {
       if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-        block_area.x += block_margin.left;
+        {
+          if (inverted)
+            block_area.x -= block_margin.right;
+          else
+            block_area.x += block_margin.left;
+        }
       else
-        block_area.y += block_margin.top;
+        {
+          if (inverted)
+            block_area.y -= block_margin.bottom;
+          else
+            block_area.y += block_margin.top;
+        }
 
       if (idx > num_filled - 1)
         gtk_style_context_add_class (context, STYLE_CLASS_EMPTY_FILL_BLOCK);
@@ -375,9 +445,19 @@ gtk_level_bar_draw_fill_discrete (GtkLevelBar           *self,
                         block_draw_width, block_draw_height);
 
       if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-        block_area.x += block_draw_width + block_margin.right;
+        {
+          if (inverted)
+            block_area.x -= block_draw_width + block_margin.left;
+          else
+            block_area.x += block_draw_width + block_margin.right;
+        }
       else
-        block_area.y += block_draw_height + block_margin.bottom;
+        {
+          if (inverted)
+            block_area.y -= block_draw_height + block_margin.top;
+          else
+            block_area.y += block_draw_height + block_margin.bottom;
+        }
     }
 
   gtk_style_context_restore (context);
@@ -388,7 +468,8 @@ gtk_level_bar_draw_fill (GtkLevelBar *self,
                          cairo_t     *cr)
 {
   GtkWidget *widget = GTK_WIDGET (self);
-  GtkBorder trough_borders; 
+  GtkBorder trough_borders;
+  gboolean inverted;
   cairo_rectangle_int_t fill_area;
 
   gtk_level_bar_get_borders (self, &trough_borders);
@@ -400,10 +481,17 @@ gtk_level_bar_draw_fill (GtkLevelBar *self,
   fill_area.height = gtk_widget_get_allocated_height (widget) -
     trough_borders.top - trough_borders.bottom;
 
+  inverted = self->priv->inverted;
+  if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
+    {
+      if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+        inverted = !inverted;
+    }
+
   if (self->priv->bar_mode == GTK_LEVEL_BAR_MODE_CONTINUOUS)
-    gtk_level_bar_draw_fill_continuous (self, cr, &fill_area);
+    gtk_level_bar_draw_fill_continuous (self, cr, inverted, &fill_area);
   else if (self->priv->bar_mode == GTK_LEVEL_BAR_MODE_DISCRETE)
-    gtk_level_bar_draw_fill_discrete (self, cr, &fill_area);
+    gtk_level_bar_draw_fill_discrete (self, cr, inverted, &fill_area);
 }
 
 static gboolean
@@ -518,8 +606,8 @@ gtk_level_bar_update_level_style_classes (GtkLevelBar *self)
       gtk_style_context_remove_class (context, offset_style_class);
 
       /* find the right offset for our style class */
-      if (((l->prev == NULL) && (value < offset->value)) ||
-          ((l->next == NULL) && (value > offset->value)))
+      if (((l->prev == NULL) && (value <= offset->value)) ||
+          ((l->next == NULL) && (value >= offset->value)))
         {
           value_class = offset_style_class;
         }
@@ -560,54 +648,73 @@ gtk_level_bar_ensure_offsets_in_range (GtkLevelBar *self)
     }
 }
 
-#define OFFSETS_ELEMENT "offsets"
-#define OFFSET_ELEMENT  "offset"
-#define OFFSET_NAME     "name"
-#define OFFSET_VALUE    "value"
-
 typedef struct {
   GtkLevelBar *self;
   GList *offsets;
 } OffsetsParserData;
 
 static void
-offset_start_element (GMarkupParseContext *context,
-                      const gchar *element_name,
-                      const gchar **names,
-                      const gchar **values,
-                      gpointer user_data,
-                      GError **error)
+offset_start_element (GMarkupParseContext  *context,
+                      const gchar          *element_name,
+                      const gchar         **names,
+                      const gchar         **values,
+                      gpointer              user_data,
+                      GError              **error)
 {
   OffsetsParserData *parser_data = user_data;
   const gchar *name = NULL;
   const gchar *value_str = NULL;
   GtkLevelBarOffset *offset;
+  gint line_number, char_number;
   gint idx;
 
-  if (strcmp (element_name, OFFSET_ELEMENT) == 0)
+  if (strcmp (element_name, "offsets") == 0)
+    ;
+  else if (strcmp (element_name, "offset") == 0)
     {
       for (idx = 0; names[idx] != NULL; idx++)
         {
-          if (strcmp (names[idx], OFFSET_NAME) == 0)
-            name = values[idx];
-          else if (strcmp (names[idx], OFFSET_VALUE) == 0)
-            value_str = values[idx];
+          if (strcmp (names[idx], "name") == 0)
+            {
+              name = values[idx];
+            }
+          else if (strcmp (names[idx], "value") == 0)
+            {
+              value_str = values[idx];
+            }
+          else
+            {
+              g_markup_parse_context_get_position (context,
+                                                   &line_number,
+                                                   &char_number);
+              g_set_error (error,
+                           GTK_BUILDER_ERROR,
+                           GTK_BUILDER_ERROR_INVALID_ATTRIBUTE,
+                           "%s:%d:%d '%s' is not a valid attribute of <%s>",
+                           "<input>",
+                           line_number, char_number, names[idx], "offset");
+
+              return;
+            }
         }
 
       if (name && value_str)
         {
-          offset = gtk_level_bar_offset_new (name, strtof (value_str, NULL));
+          offset = gtk_level_bar_offset_new (name, g_ascii_strtod (value_str, NULL));
           parser_data->offsets = g_list_prepend (parser_data->offsets, offset);
         }
     }
-  else if (strcmp (element_name, OFFSETS_ELEMENT) == 0)
-    {
-      return;
-    }
   else
     {
-      g_warning ("Unsupported type tag for GtkLevelBar: %s\n",
-                 element_name);
+      g_markup_parse_context_get_position (context,
+                                           &line_number,
+                                           &char_number);
+      g_set_error (error,
+                   GTK_BUILDER_ERROR,
+                   GTK_BUILDER_ERROR_UNHANDLED_TAG,
+                   "%s:%d:%d unsupported tag for GtkLevelBar: \"%s\"",
+                   "<input>",
+                   line_number, char_number, element_name);
     }
 }
 
@@ -617,19 +724,19 @@ static const GMarkupParser offset_parser =
 };
 
 static gboolean
-gtk_level_bar_buildable_custom_tag_start (GtkBuildable *buildable,
-                                          GtkBuilder *builder,
-                                          GObject *child,
-                                          const gchar *tagname,
+gtk_level_bar_buildable_custom_tag_start (GtkBuildable  *buildable,
+                                          GtkBuilder    *builder,
+                                          GObject       *child,
+                                          const gchar   *tagname,
                                           GMarkupParser *parser,
-                                          gpointer *data)
+                                          gpointer      *data)
 {
   OffsetsParserData *parser_data;
 
   if (child)
     return FALSE;
 
-  if (strcmp (tagname, OFFSETS_ELEMENT) != 0)
+  if (strcmp (tagname, "offsets") != 0)
     return FALSE;
 
   parser_data = g_slice_new0 (OffsetsParserData);
@@ -644,28 +751,29 @@ gtk_level_bar_buildable_custom_tag_start (GtkBuildable *buildable,
 
 static void
 gtk_level_bar_buildable_custom_finished (GtkBuildable *buildable,
-                                         GtkBuilder *builder,
-                                         GObject *child,
-                                         const gchar *tagname,
-                                         gpointer user_data)
+                                         GtkBuilder   *builder,
+                                         GObject      *child,
+                                         const gchar  *tagname,
+                                         gpointer      user_data)
 {
   OffsetsParserData *parser_data;
   GtkLevelBar *self;
   GtkLevelBarOffset *offset;
   GList *l;
 
-  if (strcmp (tagname, OFFSETS_ELEMENT) != 0)
-    return;
-
   parser_data = user_data;
   self = parser_data->self;
 
+  if (strcmp (tagname, "offsets") != 0)
+    goto out;
+
   for (l = parser_data->offsets; l != NULL; l = l->next)
     {
       offset = l->data;
       gtk_level_bar_add_offset_value (self, offset->name, offset->value);
     }
 
+ out:
   g_list_free_full (parser_data->offsets, (GDestroyNotify) gtk_level_bar_offset_free);
   g_slice_free (OffsetsParserData, parser_data);
 }
@@ -712,6 +820,9 @@ gtk_level_bar_get_property (GObject    *obj,
     case PROP_MODE:
       g_value_set_enum (value, gtk_level_bar_get_mode (self));
       break;
+    case PROP_INVERTED:
+      g_value_set_boolean (value, gtk_level_bar_get_inverted (self));
+      break;
     case PROP_ORIENTATION:
       g_value_set_enum (value, self->priv->orientation);
       break;
@@ -743,6 +854,9 @@ gtk_level_bar_set_property (GObject      *obj,
     case PROP_MODE:
       gtk_level_bar_set_mode (self, g_value_get_enum (value));
       break;
+    case PROP_INVERTED:
+      gtk_level_bar_set_inverted (self, g_value_get_boolean (value));
+      break;
     case PROP_ORIENTATION:
       gtk_level_bar_set_orientation (self, g_value_get_enum (value));
       break;
@@ -778,6 +892,20 @@ gtk_level_bar_class_init (GtkLevelBarClass *klass)
 
   g_object_class_override_property (oclass, PROP_ORIENTATION, "orientation");
 
+  /**
+   * GtkLevelBar::offset-changed:
+   * @self: a #GtkLevelBar
+   * @name: the name of the offset that changed value
+   *
+   * Emitted when an offset specified on the bar changes value as an
+   * effect to gtk_level_bar_add_offset_value() being called.
+   *
+   * The signal supports detailed connections; you can connect to the
+   * detailed signal "changed::x" in order to only receive callbacks when
+   * the value of offset "x" changes.
+   *
+   * Since: 3.6
+   */
   signals[SIGNAL_OFFSET_CHANGED] =
     g_signal_new ("offset-changed",
                   GTK_TYPE_LEVEL_BAR,
@@ -831,7 +959,7 @@ gtk_level_bar_class_init (GtkLevelBarClass *klass)
                          0.0, G_MAXDOUBLE, 1.0,
                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
   /**
-   * GtkLevelBar:bar-mode:
+   * GtkLevelBar:mode:
    *
    * The #GtkLevelBar:bar-mode property determines the way #GtkLevelBar
    * interprets the value properties to draw the level fill area.
@@ -852,13 +980,44 @@ gtk_level_bar_class_init (GtkLevelBarClass *klass)
                        GTK_LEVEL_BAR_MODE_CONTINUOUS,
                        G_PARAM_READWRITE);
 
-  gtk_widget_class_install_style_property 
+  /**
+   * GtkLevelBar:inverted:
+   *
+   * Level bars normally grow from top to bottom or left to right.
+   * Inverted level bars grow in the opposite direction.
+   *
+   * Since: 3.8
+   */
+  properties[PROP_INVERTED] =
+    g_param_spec_boolean ("inverted",
+                          P_("Inverted"),
+                          P_("Invert the direction in which the level bar grows"),
+                          FALSE,
+                          G_PARAM_READWRITE);
+
+  /**
+   * GtkLevelBar:min-block-height:
+   *
+   * The min-block-height style property determines the minimum
+   * height for blocks filling the #GtkLevelBar widget.
+   *
+   * Since: 3.6
+   */
+  gtk_widget_class_install_style_property
     (wclass, g_param_spec_int ("min-block-height",
                                P_("Minimum height for filling blocks"),
                                P_("Minimum height for blocks that fill the bar"),
                                1, G_MAXINT, DEFAULT_BLOCK_SIZE,
                                G_PARAM_READWRITE));
-  gtk_widget_class_install_style_property 
+  /**
+   * GtkLevelBar:min-block-width:
+   *
+   * The min-block-width style property determines the minimum
+   * width for blocks filling the #GtkLevelBar widget.
+   *
+   * Since: 3.6
+   */
+  gtk_widget_class_install_style_property
     (wclass, g_param_spec_int ("min-block-width",
                                P_("Minimum width for filling blocks"),
                                P_("Minimum width for blocks that fill the bar"),
@@ -867,6 +1026,8 @@ gtk_level_bar_class_init (GtkLevelBarClass *klass)
 
   g_type_class_add_private (klass, sizeof (GtkLevelBarPrivate));
   g_object_class_install_properties (oclass, LAST_PROPERTY, properties);
+
+  gtk_widget_class_set_accessible_type (wclass, GTK_TYPE_LEVEL_BAR_ACCESSIBLE);
 }
 
 static void
@@ -894,6 +1055,8 @@ gtk_level_bar_init (GtkLevelBar *self)
   self->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
   _gtk_orientable_set_style_classes (GTK_ORIENTABLE (self));
 
+  self->priv->inverted = FALSE;
+
   gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
 }
 
@@ -937,7 +1100,7 @@ gtk_level_bar_new_for_interval (gdouble min_value,
 /**
  * gtk_level_bar_get_min_value:
  * @self: a #GtkLevelBar
- * 
+ *
  * Returns the value of the #GtkLevelBar:min-value property.
  *
  * Returns: a positive value
@@ -955,7 +1118,7 @@ gtk_level_bar_get_min_value (GtkLevelBar *self)
 /**
  * gtk_level_bar_get_max_value:
  * @self: a #GtkLevelBar
- * 
+ *
  * Returns the value of the #GtkLevelBar:max-value property.
  *
  * Returns: a positive value
@@ -1002,7 +1165,7 @@ gtk_level_bar_set_value_internal (GtkLevelBar *self,
  * gtk_level_bar_set_min_value:
  * @self: a #GtkLevelBar
  * @value: a positive value
- * 
+ *
  * Sets the value of the #GtkLevelBar:min-value property.
  *
  * Since: 3.6
@@ -1030,7 +1193,7 @@ gtk_level_bar_set_min_value (GtkLevelBar *self,
  * gtk_level_bar_set_max_value:
  * @self: a #GtkLevelBar
  * @value: a positive value
- * 
+ *
  * Sets the value of the #GtkLevelBar:max-value property.
  *
  * Since: 3.6
@@ -1082,7 +1245,7 @@ gtk_level_bar_set_value (GtkLevelBar *self,
  * gtk_level_bar_get_mode:
  * @self: a #GtkLevelBar
  *
- * Returns the value of the #GtkLevelBar:bar-mode property
+ * Returns the value of the #GtkLevelBar:mode property.
  *
  * Returns: a #GtkLevelBarMode
  *
@@ -1101,7 +1264,7 @@ gtk_level_bar_get_mode (GtkLevelBar *self)
  * @self: a #GtkLevelBar
  * @mode: a #GtkLevelBarMode
  *
- * Sets the value of the #GtkLevelBar:bar-mode property
+ * Sets the value of the #GtkLevelBar:mode property.
  *
  * Since: 3.6
  */
@@ -1121,6 +1284,53 @@ gtk_level_bar_set_mode (GtkLevelBar     *self,
     }
 }
 
+/**
+ * gtk_level_bar_get_inverted:
+ * @self: a #GtkLevelBar
+ *
+ * Return the value of the #GtkLevelBar:inverted property.
+ *
+ * Return value: %TRUE if the level bar is inverted
+ *
+ * Since: 3.8
+ */
+gboolean
+gtk_level_bar_get_inverted (GtkLevelBar *self)
+{
+  g_return_val_if_fail (GTK_IS_LEVEL_BAR (self), FALSE);
+
+  return self->priv->inverted;
+}
+
+/**
+ * gtk_level_bar_set_inverted:
+ * @self: a #GtkLevelBar
+ * @inverted: %TRUE to invert the level bar
+ *
+ * Sets the value of the #GtkLevelBar:inverted property.
+ *
+ * Since: 3.8
+ */
+void
+gtk_level_bar_set_inverted (GtkLevelBar *self,
+                            gboolean     inverted)
+{
+  GtkLevelBarPrivate *priv;
+
+  g_return_if_fail (GTK_IS_LEVEL_BAR (self));
+
+  priv = self->priv;
+
+  if (priv->inverted != inverted)
+    {
+      priv->inverted = inverted;
+
+      gtk_widget_queue_resize (GTK_WIDGET (self));
+
+      g_object_notify (G_OBJECT (self), "inverted");
+    }
+}
+
 /**
  * gtk_level_bar_remove_offset_value:
  * @self: a #GtkLevelBar
@@ -1187,18 +1397,19 @@ gtk_level_bar_add_offset_value (GtkLevelBar *self,
  * gtk_level_bar_get_offset_value:
  * @self: a #GtkLevelBar
  * @name: (allow-none): the name of an offset in the bar
+ * @value: (out): location where to store the value
  *
- * Returns the value specified for the offset marker @name in @self, or
- * zero if it's not found.
+ * Fetches the value specified for the offset marker @name in @self,
+ * returning %TRUE in case an offset named @name was found.
  *
- * Returns: a value in the interval between
- *     #GtkLevelBar:min-value and #GtkLevelBar:max-value, or zero.
+ * Returns: %TRUE if the specified offset is found
  *
- * Since: 3.6 
+ * Since: 3.6
  */
-gdouble
+gboolean
 gtk_level_bar_get_offset_value (GtkLevelBar *self,
-                                const gchar *name)
+                                const gchar *name,
+                                gdouble     *value)
 {
   GList *existing;
   GtkLevelBarOffset *offset = NULL;
@@ -1209,8 +1420,11 @@ gtk_level_bar_get_offset_value (GtkLevelBar *self,
   if (existing)
     offset = existing->data;
 
-  if (offset)
-    return offset->value;
+  if (!offset)
+    return FALSE;
+
+  if (value)
+    *value = offset->value;
 
-  return 0.0;
+  return TRUE;
 }