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