Make sure that all timeouts in HildonBanner are removed
[hildon] / hildon / hildon-hvolumebar.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-hvolumebar
27  * @short_description: A widget that displays a horizontal volume bar.
28  * @see_also: #HildonVVolumebar, #HildonVolumebar
29  * 
30  * The #HildonHVolumebar widget displays a horizontal volume bar that allows
31  * increasing or decreasing volume within a pre-defined range, and includes 
32  * a mute icon which users can click to mute the sound.
33  *
34  * <note>
35  *   <para>
36  * #HildonHVolumeBar has been deprecated since Hildon 2.2
37  * See <link linkend="hildon-migrating-volume-bar">Migrating Volume Bars</link>
38  * section to know how to migrate this deprecated widget.
39  *   </para>
40  * </note>
41  *
42  * <example>
43  * <programlisting>
44  * GtkWidget *volbar = hildon_hvolumebar_new ();
45  * g_signal_connect (G_OBJECT(volbar), "mute_toggled", G_CALLBACK(mute_toggle), NULL);
46  * g_signal_connect (G_OBJECT(volbar), "level_changed", G_CALLBACK(level_change), NULL);
47  * </programlisting>
48  * </example>
49  *
50  */
51
52 #undef                                          HILDON_DISABLE_DEPRECATED
53
54 #include                                        "hildon-hvolumebar.h"
55 #include                                        "hildon-volumebar.h"
56 #include                                        "hildon-volumebar-range.h"
57 #include                                        "hildon-volumebar-private.h"
58
59 /* Defines for normal version of HVolumebar */
60 /* Toggle button */
61
62 #define                                         DEFAULT_TBUTTON_WIDTH 60
63
64 #define                                         DEFAULT_TBUTTON_HEIGHT 60
65
66 /* Volume bar */
67 #define                                         MINIMUM_BAR_WIDTH 147
68
69 #define                                         DEFAULT_BAR_HEIGHT 60
70
71 #define                                         DEFAULT_ENDING_SIZE 20
72
73 /* Gap to leave for mute button */
74 #define                                         VERTICAL_MUTE_GAP 0
75
76 #define                                         HORIZONTAL_MUTE_GAP 0
77
78 /* Sizes inside a toolbar */
79 /* Toggle button */
80
81 #define                                         TOOL_DEFAULT_TBUTTON_WIDTH 26
82
83 #define                                         TOOL_DEFAULT_TBUTTON_HEIGHT 26
84
85 /* Volumebar */
86
87 #define                                         TOOL_MINIMUM_BAR_WIDTH 121
88
89 #define                                         TOOL_DEFAULT_BAR_HEIGHT 40
90
91 #define                                         TOOL_DEFAULT_ENDING_SIZE 0
92
93 #define                                         TOOL_VERTICAL_MUTE_GAP \
94                                                 ((TOOL_DEFAULT_BAR_HEIGHT - TOOL_DEFAULT_TBUTTON_HEIGHT) / 2)
95
96 static HildonVolumebarClass*                    parent_class;
97
98 static void 
99 hildon_hvolumebar_class_init                    (HildonHVolumebarClass *klass);
100
101 static void 
102 hildon_hvolumebar_init                          (HildonHVolumebar *hvolumebar);
103
104 static gboolean
105 hildon_hvolumebar_expose                        (GtkWidget *widget,
106                                                  GdkEventExpose *event);
107 static void 
108 hildon_hvolumebar_size_request                  (GtkWidget *widget,
109                                                  GtkRequisition *requisition);
110 static void 
111 hildon_hvolumebar_size_allocate                 (GtkWidget *widget,
112                                                  GtkAllocation *allocation);
113 static void 
114 hildon_hvolumebar_map                           (GtkWidget *widget);
115
116 /**
117  * hildon_hvolumebar_get_type:
118  *
119  * Returns GType for HildonHVolumebar.
120  *
121  * Returns: HildonHVolumebar type
122  */
123 GType G_GNUC_CONST
124 hildon_hvolumebar_get_type                      (void)
125 {
126     static GType type = 0;
127
128     if (!type) {
129         static const GTypeInfo info = {
130             sizeof (HildonHVolumebarClass),
131             NULL,       /* base_init */
132             NULL,       /* base_finalize */
133             (GClassInitFunc) hildon_hvolumebar_class_init,     /* class_init */
134             NULL,       /* class_finalize */
135             NULL,       /* class_data */
136             sizeof (HildonHVolumebar),
137             0,
138             (GInstanceInitFunc) hildon_hvolumebar_init,
139         };
140         type = g_type_register_static (HILDON_TYPE_VOLUMEBAR,
141                 "HildonHVolumebar", &info, 0);
142     }
143     return type;
144 }
145
146 static void
147 hildon_hvolumebar_class_init                    (HildonHVolumebarClass *klass)
148 {
149     GtkWidgetClass *volumebar_class = GTK_WIDGET_CLASS (klass);
150
151     parent_class = g_type_class_peek_parent (klass);
152
153     volumebar_class->size_request   = hildon_hvolumebar_size_request;
154     volumebar_class->size_allocate  = hildon_hvolumebar_size_allocate;
155     volumebar_class->map            = hildon_hvolumebar_map;
156     volumebar_class->expose_event   = hildon_hvolumebar_expose;
157 }
158
159 static void 
160 hildon_hvolumebar_init                          (HildonHVolumebar *hvolumebar)
161 {
162     HildonVolumebarPrivate *priv;
163
164     priv = HILDON_VOLUMEBAR_GET_PRIVATE (hvolumebar);
165
166     priv->volumebar =
167         HILDON_VOLUMEBAR_RANGE(hildon_volumebar_range_new
168                 (GTK_ORIENTATION_HORIZONTAL));
169
170     gtk_widget_set_parent (GTK_WIDGET (priv->tbutton), GTK_WIDGET (hvolumebar));
171     gtk_widget_set_parent (GTK_WIDGET (priv->volumebar), GTK_WIDGET (hvolumebar));
172
173     gtk_scale_set_draw_value (GTK_SCALE (priv->volumebar), FALSE);
174
175     /* Signals */
176     g_signal_connect_swapped (G_OBJECT (priv->volumebar), "value-changed",
177             G_CALLBACK(hildon_volumebar_level_change),
178             hvolumebar);
179
180     g_signal_connect_swapped (priv->tbutton, "toggled",
181             G_CALLBACK (hildon_volumebar_mute_toggled), hvolumebar);
182
183     gtk_widget_show (GTK_WIDGET (priv->volumebar));
184 }
185
186 /**
187  * hildon_hvolumebar_new:
188  *
189  * Creates a new #HildonHVolumebar widget.
190  *
191  * Returns: a new #HildonHVolumebar
192  */
193 GtkWidget*
194 hildon_hvolumebar_new                           (void)
195 {
196     return GTK_WIDGET (g_object_new(HILDON_TYPE_HVOLUMEBAR, NULL));
197 }
198
199 static void 
200 hildon_hvolumebar_map                           (GtkWidget* widget)
201 {
202     HildonVolumebarPrivate *priv;
203     GtkWidget *parent;
204
205     priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
206     g_assert (priv);
207
208     parent = gtk_widget_get_ancestor (GTK_WIDGET (widget), GTK_TYPE_TOOLBAR);
209
210     /* Check if the volumebar is in a toolbar */
211     if (parent)
212         priv->is_toolbar = TRUE;
213
214     GTK_WIDGET_CLASS (parent_class)->map (widget);
215 }
216
217 static gboolean 
218 hildon_hvolumebar_expose                        (GtkWidget * widget,
219                                                  GdkEventExpose * event)
220 {
221     HildonVolumebarPrivate *priv;
222
223     priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
224     g_assert (priv);
225
226     if (GTK_WIDGET_DRAWABLE (widget)) {
227         /* Paint background */
228         gtk_paint_box (widget->style, widget->window,
229                 GTK_WIDGET_STATE (priv->volumebar), GTK_SHADOW_OUT,
230                 NULL, widget, "background",
231                 widget->allocation.x,
232                 widget->allocation.y,
233                 widget->allocation.width,
234                 widget->allocation.height);
235
236         /* The contents of the widget can paint themselves */
237         /* FIXME Not sure if this is even needed here */
238         (*GTK_WIDGET_CLASS(parent_class)->expose_event) (widget, event);
239     }
240
241     return FALSE;
242 }
243
244 static void
245 hildon_hvolumebar_size_request                  (GtkWidget * widget,
246                                                  GtkRequisition * requisition)
247 {
248     HildonVolumebarPrivate *priv;
249
250     priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
251     g_assert (priv);
252
253     /* Volumebar has different dimensions in toolbar */
254     requisition->width = (priv->is_toolbar
255             ? TOOL_MINIMUM_BAR_WIDTH
256             : MINIMUM_BAR_WIDTH);
257
258     requisition->height = (priv->is_toolbar
259             ? TOOL_DEFAULT_BAR_HEIGHT
260             : DEFAULT_BAR_HEIGHT);
261 }
262
263 static void
264 hildon_hvolumebar_size_allocate                 (GtkWidget * widget,
265                                                  GtkAllocation * allocation)
266 {
267     HildonVolumebarPrivate *priv;
268     GtkAllocation button_allocation, range_allocation;
269
270     priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
271     g_assert (priv);
272
273     button_allocation.x = 0;
274     button_allocation.width = 0;
275
276     /* Center the widget vertically */
277     if (priv->is_toolbar && allocation->height > TOOL_DEFAULT_BAR_HEIGHT) {
278         allocation->y += (allocation->height - TOOL_DEFAULT_BAR_HEIGHT) / 2;
279         allocation->height = TOOL_DEFAULT_BAR_HEIGHT;
280     }
281
282     if (!priv->is_toolbar && allocation->height > DEFAULT_BAR_HEIGHT) {
283         allocation->y += (allocation->height - DEFAULT_BAR_HEIGHT) / 2;
284         allocation->height = DEFAULT_BAR_HEIGHT;
285     }
286
287     GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
288
289     if (priv->tbutton && GTK_WIDGET_VISIBLE (priv->tbutton)) {
290
291         /* Allocate space for the mute button */
292         if (priv->is_toolbar) {
293             button_allocation.x = allocation->x;
294             button_allocation.y = allocation->y + TOOL_VERTICAL_MUTE_GAP;
295             button_allocation.width = TOOL_DEFAULT_TBUTTON_WIDTH;
296             button_allocation.height = TOOL_DEFAULT_TBUTTON_HEIGHT;
297         } else {
298             button_allocation.x = allocation->x + DEFAULT_ENDING_SIZE;
299             button_allocation.y = allocation->y + VERTICAL_MUTE_GAP;
300             button_allocation.width = DEFAULT_TBUTTON_WIDTH;
301             button_allocation.height = DEFAULT_TBUTTON_HEIGHT;
302         }
303         gtk_widget_size_allocate (GTK_WIDGET (priv->tbutton),
304                 &button_allocation);
305     }
306     if (priv->volumebar && GTK_WIDGET_VISIBLE (priv->volumebar)) {
307
308         /* Allocate space for the slider */
309         range_allocation.y = allocation->y;
310
311         if (priv->tbutton && GTK_WIDGET_VISIBLE (priv->tbutton))
312         {
313             /* Leave room for the mute button */
314             range_allocation.x = button_allocation.x
315                 + button_allocation.width
316                 + HORIZONTAL_MUTE_GAP;
317
318             if (priv->is_toolbar) 
319             {
320                 /* In toolbar with mute button */
321                 range_allocation.width = MAX(0,
322                         allocation->width
323                         - 2 * TOOL_DEFAULT_ENDING_SIZE
324                         - TOOL_DEFAULT_TBUTTON_WIDTH
325                         - HORIZONTAL_MUTE_GAP);
326
327                 range_allocation.height = TOOL_DEFAULT_BAR_HEIGHT;
328
329             } 
330
331             else 
332             {
333                 /* Standalone with mute button */
334                 range_allocation.width = MAX(0,
335                         allocation->width
336                         - 2 * DEFAULT_ENDING_SIZE
337                         - DEFAULT_TBUTTON_WIDTH
338                         - HORIZONTAL_MUTE_GAP);
339
340                 range_allocation.height = DEFAULT_BAR_HEIGHT;
341             }
342
343         }
344
345         else
346         {
347             if (priv->is_toolbar) 
348             {
349                 /* In toolbar without mute button */
350                 range_allocation.x = allocation->x;
351
352                 range_allocation.width = MAX(0,
353                         allocation->width
354                         - 2 * TOOL_DEFAULT_ENDING_SIZE );
355
356                 range_allocation.height = TOOL_DEFAULT_BAR_HEIGHT;
357
358             } 
359
360             else 
361             {
362                 /* Standalone without mute button */
363                 range_allocation.x = allocation->x + DEFAULT_ENDING_SIZE;
364
365                 range_allocation.width = MAX(0,
366                         allocation->width
367                         - 2 * DEFAULT_ENDING_SIZE );
368
369                 range_allocation.height = DEFAULT_BAR_HEIGHT;
370             }
371         }
372
373         gtk_widget_size_allocate (GTK_WIDGET (priv->volumebar),
374                 &range_allocation);
375     }
376 }
377