2008-03-03 Sven Herzberg <sven@imendio.com>
[hildon] / src / hildon-volumebar.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
5  *
6  * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24
25 /**
26  * SECTION:hildon-volumebar
27  * @short_description: Base class for widgets that display a volume bar.
28  * @see_also: #HildonHVolumebar, #HildonVVolumebar
29  *
30  * #HildonVolumebar is a base class for widgets that display a volume bar that
31  * allows increasing or decreasing volume within a predefined range, and muting
32  * the volume when users click the mute icon.
33  */
34
35 #ifdef                                          HAVE_CONFIG_H
36 #include                                        <config.h>
37 #endif
38
39 #include                                        "hildon-volumebar.h"
40 #include                                        <gtk/gtk.h>
41 #include                                        <gdk/gdkkeysyms.h>
42 #include                                        "hildon-volumebar-range.h"
43 #include                                        "hildon-volumebar-private.h"
44
45 static GtkContainerClass*                       parent_class;
46
47 static void
48 hildon_volumebar_class_init                     (HildonVolumebarClass* volumebar_class);       
49
50 static void 
51 hildon_volumebar_init                           (HildonVolumebar* volumebar);
52
53 static void 
54 hildon_child_forall                             (GtkContainer * container,
55                                                  gboolean include_internals,
56                                                  GtkCallback callback,
57                                                  gpointer callback_data);
58
59 static void 
60 hildon_volumebar_destroy                        (GtkObject *self);
61
62 static void 
63 hildon_volumebar_set_property                   (GObject* object,
64                                                  guint prop_id,
65                                                  const GValue* value,
66                                                  GParamSpec* pspec);
67
68 static void 
69 hildon_volumebar_get_property                   (GObject * object,
70                                                  guint prop_id,
71                                                  GValue* value, 
72                                                  GParamSpec* pspec);
73
74 static void 
75 mute_toggled                                    (HildonVolumebar *self);
76
77 static gboolean
78 hildon_volumebar_key_press                      (GtkWidget* widget,
79                                                  GdkEventKey* event);
80
81 static void 
82 hildon_volumebar_size_allocate                  (GtkWidget *widget,
83                                                  GtkAllocation *allocation);
84
85 static void 
86 hildon_volumebar_realize                        (GtkWidget *widget);
87
88 static void 
89 hildon_volumebar_unrealize                      (GtkWidget *widget);
90
91 static void 
92 hildon_volumebar_map                            (GtkWidget *widget);
93
94 static void 
95 hildon_volumebar_unmap                          (GtkWidget *widget);
96
97 static void 
98 hildon_volumebar_notify                         (GObject *self, GParamSpec *param);
99
100 enum 
101 {
102     MUTE_TOGGLED_SIGNAL,
103     LEVEL_CHANGED_SIGNAL,
104     LAST_SIGNAL
105 };
106
107 enum {
108     PROP_0,
109     PROP_HILDON_HAS_MUTE,
110     PROP_HILDON_FOCUSABLE,
111     PROP_HILDON_LEVEL,
112     PROP_HILDON_MUTE
113 };
114
115 static guint                                    signals [LAST_SIGNAL] = { 0 };
116
117 /**
118  * hildon_volumebar_get_type:
119  *
120  * Initializes and returns the type of a hildon volumebar.
121  *
122  * @Returns: GType of #HildonVolumebar
123  */
124 GType G_GNUC_CONST 
125 hildon_volumebar_get_type                       (void)
126 {
127     static GType volumebar_type = 0;
128
129     if (!volumebar_type) {
130         static const GTypeInfo volumebar_info = {
131             sizeof(HildonVolumebarClass),
132             NULL,       /* base_init */
133             NULL,       /* base_finalize */
134             (GClassInitFunc) hildon_volumebar_class_init,
135             NULL,       /* class_finalize */
136             NULL,       /* class_data */
137             sizeof(HildonVolumebar),
138             0,  /* n_preallocs */
139             (GInstanceInitFunc) hildon_volumebar_init,
140         };
141         volumebar_type = g_type_register_static(GTK_TYPE_CONTAINER,
142                 "HildonVolumebar",
143                 &volumebar_info, 0);
144     }
145     return volumebar_type;
146 }
147
148 static void 
149 hildon_volumebar_class_init                     (HildonVolumebarClass *volumebar_class)
150 {
151     GObjectClass      *gobject_class    = G_OBJECT_CLASS  (volumebar_class);
152     GtkObjectClass    *object_class     = GTK_OBJECT_CLASS (volumebar_class);
153     GtkWidgetClass    *widget_class     = GTK_WIDGET_CLASS (volumebar_class);
154     GtkContainerClass *container_class  = GTK_CONTAINER_CLASS (volumebar_class);
155
156     parent_class = g_type_class_peek_parent (volumebar_class);
157
158     g_type_class_add_private (volumebar_class,
159             sizeof (HildonVolumebarPrivate));
160
161    /* Because we derived our widget from GtkContainer, we should also
162     * override forall method 
163     */
164    volumebar_class->mute_toggled        = mute_toggled;
165    container_class->forall              = hildon_child_forall;
166    widget_class->size_allocate          = hildon_volumebar_size_allocate;
167    widget_class->realize                = hildon_volumebar_realize;
168    widget_class->unrealize              = hildon_volumebar_unrealize;
169    widget_class->map                    = hildon_volumebar_map;
170    widget_class->unmap                  = hildon_volumebar_unmap;
171    widget_class->key_press_event        = hildon_volumebar_key_press;
172    object_class->destroy                = hildon_volumebar_destroy;
173
174    signals[MUTE_TOGGLED_SIGNAL] = g_signal_new ("mute_toggled",
175            G_OBJECT_CLASS_TYPE
176            (object_class),
177            G_SIGNAL_RUN_LAST |
178            G_SIGNAL_ACTION,
179            G_STRUCT_OFFSET
180            (HildonVolumebarClass,
181             mute_toggled), NULL, NULL,
182            gtk_marshal_VOID__VOID,
183            G_TYPE_NONE, 0);
184
185    signals[LEVEL_CHANGED_SIGNAL] = g_signal_new ("level_changed",
186            G_OBJECT_CLASS_TYPE
187            (object_class),
188            G_SIGNAL_RUN_LAST |
189            G_SIGNAL_ACTION,
190            G_STRUCT_OFFSET
191            (HildonVolumebarClass,
192             level_changed), NULL,
193            NULL,
194            gtk_marshal_VOID__VOID,
195            G_TYPE_NONE, 0);
196
197    gobject_class->notify                = hildon_volumebar_notify;
198    gobject_class->set_property          = hildon_volumebar_set_property;
199    gobject_class->get_property          = hildon_volumebar_get_property; 
200
201    /**
202     * HildonVolumebar:can-focus:
203     *
204     * The widget focusability.
205     */
206    g_object_class_install_property (gobject_class,
207            PROP_HILDON_FOCUSABLE, 
208            g_param_spec_boolean ("can-focus",
209                "The widget focusablility",
210                "The widget focusablility. TRUE is focusable",
211                TRUE,
212                G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
213
214    /**
215     * HildonVolumebar:has-mute:
216     *
217     * Whether the mute button is visibile.
218     */
219    g_object_class_install_property (gobject_class,
220            PROP_HILDON_HAS_MUTE, 
221            g_param_spec_boolean ("has_mute",
222                "Show/Hide the mute button",
223                "Whether the mute button is visible. Default value: TRUE",
224                TRUE,
225                G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
226
227    /**
228     * HildonVolumebar:level:
229     *
230     * Current volume level.
231     */
232    g_object_class_install_property (gobject_class,
233            PROP_HILDON_LEVEL,
234            g_param_spec_double ("level",
235                "Level",
236                "Current volume level",
237                0.0,
238                100.0,
239                50.0,
240                G_PARAM_READWRITE));
241
242    /**
243     * HildonVolumebar:mute:
244     *
245     * Whether volume is muted.
246     */
247    g_object_class_install_property (gobject_class,
248            PROP_HILDON_MUTE,
249            g_param_spec_boolean ("mute",
250                "Mute",
251                "Whether volume is muted",
252                FALSE,
253                G_PARAM_READWRITE));
254 }
255
256 static void 
257 hildon_volumebar_init                           (HildonVolumebar *volumebar)
258 {
259     HildonVolumebarPrivate *priv;
260
261     priv = HILDON_VOLUMEBAR_GET_PRIVATE(volumebar);
262     g_assert (priv);
263
264     /* Should set GTK_NO_WINDOW flag, because widget is derived from
265        GtkContainer */
266     GTK_WIDGET_SET_FLAGS (GTK_WIDGET (volumebar), GTK_NO_WINDOW);
267     GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (volumebar), GTK_CAN_FOCUS);
268
269     /* Initialize mute button */
270     priv->tbutton = GTK_TOGGLE_BUTTON (gtk_toggle_button_new ());
271     g_object_set (G_OBJECT (priv->tbutton), "can-focus", FALSE, NULL);
272 }
273
274 static void
275 hildon_volumebar_size_allocate                  (GtkWidget *widget, 
276                                                  GtkAllocation *allocation)
277 {
278     HildonVolumebarPrivate *priv;
279
280     priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
281     g_assert (priv);
282
283     if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
284         GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
285
286     if (GTK_WIDGET_REALIZED (widget))
287         gdk_window_move_resize (priv->event_window,
288                 allocation->x, allocation->y,
289                 allocation->width, allocation->height);
290 }
291
292 static void
293 hildon_volumebar_realize                        (GtkWidget *widget)
294 {
295     HildonVolumebarPrivate *priv;
296     GdkWindowAttr attributes;
297     gint attributes_mask;
298
299     priv = HILDON_VOLUMEBAR_GET_PRIVATE (widget);
300     g_assert (priv);
301
302     GTK_WIDGET_CLASS (parent_class)->realize (widget);
303
304     attributes.window_type = GDK_WINDOW_CHILD;
305     attributes.x = widget->allocation.x;
306     attributes.y = widget->allocation.y;
307     attributes.width = widget->allocation.width;
308     attributes.height = widget->allocation.height;
309     attributes.wclass = GDK_INPUT_ONLY;
310     attributes.event_mask = GDK_BUTTON_PRESS_MASK;
311
312     attributes_mask = GDK_WA_X | GDK_WA_Y;
313
314     priv->event_window = gdk_window_new (widget->window,
315             &attributes, attributes_mask);
316
317     gdk_window_set_user_data (priv->event_window, widget);
318 }
319
320 static void
321 hildon_volumebar_unrealize                      (GtkWidget *widget)
322 {
323     HildonVolumebarPrivate *priv;
324
325     priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
326     g_assert (priv);
327
328     if (priv->event_window) {
329         gdk_window_set_user_data (priv->event_window, NULL);
330         gdk_window_destroy (priv->event_window);
331         priv->event_window = NULL;
332     }
333
334     GTK_WIDGET_CLASS (parent_class)->unrealize(widget);
335 }
336
337 static void
338 hildon_volumebar_map                            (GtkWidget *widget)
339 {
340     HildonVolumebarPrivate *priv;
341
342     priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
343     g_assert (priv);
344
345     GTK_WIDGET_CLASS (parent_class)->map (widget);
346
347     /* the event window must be on top of all other widget windows, so show it
348      * last */
349     if (! GTK_WIDGET_SENSITIVE (widget))
350         gdk_window_show (priv->event_window);
351 }
352
353 static void 
354 hildon_volumebar_unmap                          (GtkWidget *widget)
355 {
356     HildonVolumebarPrivate *priv;
357
358     priv = HILDON_VOLUMEBAR_GET_PRIVATE (widget);
359     g_assert (priv);
360
361     gdk_window_hide (priv->event_window);
362
363     GTK_WIDGET_CLASS (parent_class)->unmap(widget);
364 }
365
366 static void
367 hildon_child_forall                             (GtkContainer *container,
368                                                  gboolean include_internals,
369                                                  GtkCallback callback, 
370                                                  gpointer callback_data)
371 {
372     HildonVolumebarPrivate *priv;
373
374     priv = HILDON_VOLUMEBAR_GET_PRIVATE (container);
375     g_assert (callback != NULL);
376     g_assert (priv);
377
378     /* No external children */
379     if (! include_internals)
380         return;
381
382     /* Execute callback for both internals */
383     (*callback) (GTK_WIDGET (priv->tbutton), callback_data);
384     (*callback) (GTK_WIDGET (priv->volumebar), callback_data);
385 }
386
387 static void
388 hildon_volumebar_notify                         (GObject *self, 
389                                                  GParamSpec *param)
390 {
391     HildonVolumebarPrivate *priv;
392
393     priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
394     g_assert (priv);
395
396     if (GTK_WIDGET_MAPPED (self)) {
397         /* show/hide the event window on sensitivity change */
398         if (g_str_equal (param->name, "sensitive")) {
399             if (GTK_WIDGET_SENSITIVE (self))
400                 gdk_window_hide (priv->event_window);
401             else
402                 gdk_window_show (priv->event_window);
403         }
404     }
405
406     if (G_OBJECT_CLASS(parent_class)->notify)
407         G_OBJECT_CLASS(parent_class)->notify (self, param);
408 }
409
410 static void 
411 hildon_volumebar_destroy                        (GtkObject *self)
412 {
413     HildonVolumebarPrivate *priv;
414
415     priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
416     g_assert (priv);
417
418     if (priv->tbutton) {
419         gtk_widget_unparent (GTK_WIDGET (priv->tbutton));
420         priv->tbutton = NULL;
421     }
422     if (priv->volumebar) {
423         gtk_widget_unparent (GTK_WIDGET (priv->volumebar));
424         priv->volumebar = NULL;
425     }
426
427     if (GTK_OBJECT_CLASS (parent_class)->destroy)
428         GTK_OBJECT_CLASS (parent_class)->destroy (self);
429 }
430
431 static void
432 hildon_volumebar_set_property                   (GObject *object,
433                                                  guint prop_id,
434                                                  const GValue *value, 
435                                                  GParamSpec *pspec)
436 {  
437     HildonVolumebarPrivate *priv;
438
439     priv = HILDON_VOLUMEBAR_GET_PRIVATE(object);
440     g_assert (priv);
441
442     switch (prop_id) {
443
444         case PROP_HILDON_HAS_MUTE:
445             /* Mute button always exists but might be hidden */
446             if (g_value_get_boolean (value))
447                 gtk_widget_show (GTK_WIDGET (priv->tbutton));
448             else
449                 gtk_widget_hide (GTK_WIDGET (priv->tbutton));
450             break;
451
452         case PROP_HILDON_FOCUSABLE:
453             g_object_set (G_OBJECT (priv->volumebar), "can-focus", 
454                     g_value_get_boolean (value), NULL );
455             break;
456
457         case PROP_HILDON_LEVEL:
458             hildon_volumebar_set_level (HILDON_VOLUMEBAR (object),
459                     g_value_get_double (value));
460             break;
461
462         case PROP_HILDON_MUTE:
463             hildon_volumebar_set_mute (HILDON_VOLUMEBAR (object),
464                     g_value_get_boolean (value));
465             break;
466
467         default:
468             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
469
470             break;
471     }
472 }
473
474 static void
475 hildon_volumebar_get_property                   (GObject *object,
476                                                  guint prop_id, 
477                                                  GValue *value, 
478                                                  GParamSpec *pspec)
479 {
480     HildonVolumebarPrivate *priv;
481     HildonVolumebar *vb;
482         
483     priv = HILDON_VOLUMEBAR_GET_PRIVATE(object);
484     g_assert (priv);
485
486     vb = HILDON_VOLUMEBAR (object);
487
488     switch (prop_id) {
489
490         case PROP_HILDON_HAS_MUTE:
491             g_value_set_boolean (value, GTK_WIDGET_VISIBLE (priv->tbutton));
492             break;
493
494         case PROP_HILDON_FOCUSABLE:
495             g_value_set_boolean (value, GTK_WIDGET_CAN_FOCUS (priv->volumebar));
496             break;
497
498         case PROP_HILDON_LEVEL:
499             g_value_set_double (value, hildon_volumebar_get_level (vb));
500             break;
501
502         case PROP_HILDON_MUTE:
503             g_value_set_boolean (value, hildon_volumebar_get_mute (vb));
504             break;
505
506         default:
507             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
508             break;
509
510     }
511 }
512
513 /**
514  * hildon_volumebar_set_level:
515  * @self: volume bar to change level on
516  * @level: new level
517  *
518  * Sets new volume level for this #HildonVolumebar.
519  */
520 void 
521 hildon_volumebar_set_level                      (HildonVolumebar *self, 
522                                                  gdouble level)
523 {
524     HildonVolumebarPrivate *priv;
525
526     g_return_if_fail(HILDON_IS_VOLUMEBAR (self));
527
528     priv = HILDON_VOLUMEBAR_GET_PRIVATE (self);
529     g_assert (priv);
530
531     hildon_volumebar_range_set_level (priv->volumebar, level);
532 }
533
534 /**
535  * hildon_volumebar_get_level:
536  * @self: volume bar to query level on
537  *
538  * Gets the volume level of this #HildonVolumebar.
539  *
540  * Returns: volume level or -1 on error
541  */
542 gdouble 
543 hildon_volumebar_get_level                      (HildonVolumebar *self)
544 {
545     HildonVolumebarPrivate *priv;
546
547     g_return_val_if_fail(HILDON_IS_VOLUMEBAR (self), -1);
548
549     priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
550     g_assert (priv);
551
552     return hildon_volumebar_range_get_level (priv->volumebar);
553 }
554
555 /**
556  * hildon_volumebar_set_mute:
557  * @self: volume bar to work on
558  * @mute: mute ON/OFF
559  *
560  * Sets mute status for this #HildonVolumebar.
561  */
562 void 
563 hildon_volumebar_set_mute                       (HildonVolumebar *self, 
564                                                  gboolean mute)
565 {
566     HildonVolumebarPrivate *priv;
567     gboolean focusable;
568     gboolean volumebar_has_focus;
569     gboolean button_has_focus;
570
571     g_return_if_fail (HILDON_IS_VOLUMEBAR (self));
572
573     priv = HILDON_VOLUMEBAR_GET_PRIVATE (self);
574     g_assert (priv);
575
576     volumebar_has_focus = GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (priv->volumebar));
577     button_has_focus = GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (priv->tbutton));
578
579     /* Slider should be insensitive when mute is on */
580     gtk_widget_set_sensitive (GTK_WIDGET (priv->volumebar), !mute);
581     
582     focusable = GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (priv->volumebar));
583
584     if (mute){   
585         if (focusable && volumebar_has_focus) {
586             /* Make mute button focusable since the slider isn't anymore */
587             g_object_set (G_OBJECT (priv->tbutton), "can-focus", TRUE, NULL);
588             gtk_widget_grab_focus (GTK_WIDGET (priv->tbutton));
589         }
590     }
591     else
592     {
593         g_object_set (G_OBJECT (priv->tbutton), "can-focus", FALSE, NULL);
594
595         /* Mute off grabs focus */
596         if (focusable && button_has_focus){
597             gtk_widget_grab_focus (GTK_WIDGET (priv->volumebar));
598         }
599     }
600
601     /* Update mute button state and redraw */
602     gtk_toggle_button_set_active (priv->tbutton, mute);
603
604     /* FIXME I'm darn sure that's not really needed */
605     gtk_widget_queue_draw (GTK_WIDGET (self));
606 }
607
608 /**
609  * hildon_volumebar_get_mute:
610  * @self: volume bar to query mute status
611  *
612  * Gets mute status of this #HildonVolumebar (ON/OFF).
613  *
614  * Returns: Mute status as #gboolean value.
615  */
616 gboolean 
617 hildon_volumebar_get_mute                       (HildonVolumebar *self)
618 {
619     HildonVolumebarPrivate *priv;
620
621     g_return_val_if_fail (HILDON_IS_VOLUMEBAR (self), TRUE);
622
623     priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
624     g_assert (priv);
625
626     return gtk_toggle_button_get_active (priv->tbutton);
627 }
628
629 /**
630  * hildon_volumebar_get_adjustment
631  * @self : a #HildonVolumebar
632  * 
633  * Gets the GtkAdjustment used in volume bar. This can be handy
634  * to pass to hildon_appview_set_connected_adjustment which
635  * will allow changing the volume with 'increase' / 'decrease'
636  * hardware buttons.
637  *
638  * Returns: a #GtkAdjustment used by volume bar.
639  */
640 GtkAdjustment* 
641 hildon_volumebar_get_adjustment                 (HildonVolumebar *self)
642 {
643     HildonVolumebarPrivate *priv;
644
645     g_return_val_if_fail(HILDON_IS_VOLUMEBAR(self), NULL);
646
647     priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
648     g_assert (priv);
649
650     return gtk_range_get_adjustment (GTK_RANGE (priv->volumebar));
651 }
652
653 static void
654 mute_toggled                                    (HildonVolumebar *self)
655 {
656     /* This looks like no-op, but it still does something meaningfull!
657        set_mute also updates the ui to match new state that
658        is already reported by get_mute */
659
660     hildon_volumebar_set_mute (self, hildon_volumebar_get_mute (self));
661 }
662
663 static gboolean
664 hildon_volumebar_key_press                      (GtkWidget *widget,
665                                                  GdkEventKey *event)
666 {
667     HildonVolumebarPrivate *priv;
668
669     priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
670     g_assert (priv != NULL);
671
672     /* Enter key toggles mute button (unless it is hidden) */
673     if (event->keyval == GDK_Return && GTK_WIDGET_VISIBLE (priv->tbutton)) {
674         gtk_toggle_button_set_active (priv->tbutton, 
675                 ! hildon_volumebar_get_mute(HILDON_VOLUMEBAR(widget)));
676
677         return TRUE;
678     }
679
680     return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
681 }
682
683 /* 
684  * Sends mute-toggled signal to widget, used as a callback in derived classes.
685  */
686 void G_GNUC_INTERNAL
687 hildon_volumebar_mute_toggled                   (HildonVolumebar * self)
688 {
689     g_return_if_fail (HILDON_IS_VOLUMEBAR (self));
690     /* FIXME Emit by id */
691     g_signal_emit_by_name (self, "mute_toggled");
692 }
693
694 void G_GNUC_INTERNAL 
695 hildon_volumebar_level_change                   (HildonVolumebar *self)
696 {
697     g_return_if_fail (HILDON_IS_VOLUMEBAR (self));
698
699     /* FIXME Use numerical val, id */
700     g_signal_emit_by_name (GTK_WIDGET (self), "level_changed");
701 }
702
703 /**
704  * hildon_volumebar_set_range_insensitive_message:
705  * @widget: A @GtkWidget to assign the banner to 
706  * @message: A message to display to the user
707  *
708  * Used to asign an insensitive message to the slider of the given volumebar.
709  * It simply calls hildon_helper_set_insensitive_message on the slider/range of 
710  * the volumebar. 
711  */
712 void
713 hildon_volumebar_set_range_insensitive_message  (HildonVolumebar *widget,
714                                                  const gchar *message)
715 {
716     g_return_if_fail (HILDON_IS_VOLUMEBAR (widget));
717
718     HildonVolumebarPrivate *priv;
719     priv = HILDON_VOLUMEBAR_GET_PRIVATE (widget);
720
721     hildon_helper_set_insensitive_message ((GtkWidget *) priv->volumebar, message);
722 }
723
724 /**
725  * hildon_volumebar_set_range_insensitive_messagef:
726  * @widget: A @GtkWidget to assign the banner to 
727  * @format : a printf-like format string
728  * @varargs : arguments for the format string
729  *
730  * A helper printf-like variant of hildon_helper_set_insensitive_message.
731  */
732 void
733 hildon_volumebar_set_range_insensitive_messagef (HildonVolumebar *widget,
734                                                  const gchar *format,
735                                                  ...)
736 {
737     g_return_if_fail (HILDON_IS_VOLUMEBAR (widget));
738
739     HildonVolumebarPrivate *priv;
740     priv = HILDON_VOLUMEBAR_GET_PRIVATE (widget);
741
742     gchar *message;
743     va_list args;
744
745     va_start (args, format);
746     message = g_strdup_vprintf (format, args);
747     va_end (args);
748
749     hildon_helper_set_insensitive_message ((GtkWidget *) priv->volumebar, message);
750
751     g_free (message);
752 }
753
754