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