Put function name in the changelog.
[hildon] / src / hildon-vvolumebar.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-vvolumebar
27  * @short_description: A widget that displays a vertical volume bar.
28  * @see_also: #HildonVolumebar, #HildonHVolumebar
29  *
30  * #HildonVVolumebar is a subclass of #HildonVolumebar.  It displays a
31  * vertical volume bar that allows increasing or decreasing volume
32  * within a predefined range, and muting when users click the mute icon.
33  * 
34  * Here is an example that creates a vertical volume bar and connects
35  * both its signals.
36  * <example>
37  * <title>HildonVVolumebar example</title>
38  * <programlisting>
39  * GtkWidget *volbar = hildon_vvolumebar_new ();
40  * g_signal_connect (G_OBJECT (volbar), "mute_toggled", G_CALLBACK (mute_toggle), NULL);
41  * g_signal_connect (G_OBJECT (volbar), "level_changed", G_CALLBACK (level_change), NULL);
42  * </programlisting>
43  * </example>
44  */
45
46 #ifdef                                          HAVE_CONFIG_H
47 #include                                        <config.h>
48 #endif
49
50 #include                                        "hildon-vvolumebar.h"
51 #include                                        <gtk/gtk.h>
52 #include                                        "hildon-volumebar-range.h"
53 #include                                        "hildon-volumebar-private.h"
54
55 /* Volume bar */
56 #define                                         DEFAULT_BAR_WIDTH 58
57
58 #define                                         MINIMUM_BAR_HEIGHT 165
59
60 /* Toggle button */
61
62 #define                                         DEFAULT_VERTICAL_TBUTTON_WIDTH 26
63
64 #define                                         DEFAULT_VERTICAL_TBUTTON_HEIGHT 26
65
66 #define                                         DEFAULT_ENDING_SIZE 20
67
68 /* Gap to leave for mute button */
69
70 #define                                         HORIZONTAL_MUTE_GAP 16
71
72 #define                                         VERTICAL_MUTE_GAP 6
73
74 static HildonVolumebarClass*                    parent_class;
75
76 static void 
77 hildon_vvolumebar_class_init                    (HildonVVolumebarClass * klass);
78
79 static void 
80 hildon_vvolumebar_init                          (HildonVVolumebar * vvolumebar);
81
82 static gboolean
83 hildon_vvolumebar_expose                        (GtkWidget * widget,
84                                                  GdkEventExpose * event);
85
86 static void 
87 hildon_vvolumebar_size_request                  (GtkWidget * widget,
88                                                  GtkRequisition * requisition);
89
90 static void
91 hildon_vvolumebar_size_allocate                 (GtkWidget * widget,
92                                                  GtkAllocation * allocation);
93
94 /**
95  * hildon_vvolumebar_get_type:
96  *
97  * Initializes and returns the type of a hildon vvolumebar.
98  *
99  * @Returns: GType of #HildonVVolumebar
100  */
101 GType G_GNUC_CONST
102 hildon_vvolumebar_get_type                      (void)
103 {
104     static GType type = 0;
105
106     if (!type) {
107         static const GTypeInfo info = {
108             sizeof (HildonVVolumebarClass),
109             NULL,       /* base_init */
110             NULL,       /* base_finalize */
111             (GClassInitFunc) hildon_vvolumebar_class_init,     /* class_init */
112             NULL,       /* class_finalize */
113             NULL,       /* class_data */
114             sizeof (HildonVVolumebar),
115             0,
116             (GInstanceInitFunc) hildon_vvolumebar_init,
117         };
118         type =
119             g_type_register_static (HILDON_TYPE_VOLUMEBAR,
120                     "HildonVVolumebar", &info, 0);
121     }
122     return type;
123 }
124
125 static void 
126 hildon_vvolumebar_class_init                    (HildonVVolumebarClass *klass)
127 {
128     GtkWidgetClass *volumebar_class = GTK_WIDGET_CLASS(klass);
129
130     parent_class = g_type_class_peek_parent(klass);
131
132     volumebar_class->size_request   = hildon_vvolumebar_size_request;
133     volumebar_class->size_allocate  = hildon_vvolumebar_size_allocate;
134     volumebar_class->expose_event   = hildon_vvolumebar_expose;
135 }
136
137 static void 
138 hildon_vvolumebar_init                          (HildonVVolumebar *vvolumebar)
139 {
140     HildonVolumebarPrivate *priv;
141
142     priv = HILDON_VOLUMEBAR_GET_PRIVATE (vvolumebar);
143     g_assert (priv);
144
145     priv->volumebar = HILDON_VOLUMEBAR_RANGE (hildon_volumebar_range_new
146             (GTK_ORIENTATION_VERTICAL));
147
148     GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (vvolumebar), GTK_CAN_FOCUS);
149
150     gtk_widget_set_parent (GTK_WIDGET (priv->tbutton), GTK_WIDGET (vvolumebar));
151     gtk_widget_set_parent (GTK_WIDGET (priv->volumebar), GTK_WIDGET (vvolumebar));
152
153     gtk_scale_set_draw_value (GTK_SCALE (priv->volumebar), FALSE);
154
155     /* Signals */
156     g_signal_connect_swapped(G_OBJECT(priv->volumebar), "value-changed",
157             G_CALLBACK(hildon_volumebar_level_change),
158             vvolumebar);
159
160     g_signal_connect_swapped(priv->tbutton, "toggled",
161             G_CALLBACK(hildon_volumebar_mute_toggled), vvolumebar);
162
163     /* FIXME Not sure why this is here */
164     gtk_widget_show (GTK_WIDGET (priv->volumebar));
165 }
166
167 /**
168  * hildon_vvolumebar_new:
169  *
170  * Creates a new #HildonVVolumebar widget.
171  *
172  * Returns: a new #HildonVVolumebar
173  */
174 GtkWidget*
175 hildon_vvolumebar_new                           (void)
176 {
177     return GTK_WIDGET (g_object_new(HILDON_TYPE_VVOLUMEBAR, NULL));
178 }
179
180 static gboolean 
181 hildon_vvolumebar_expose                        (GtkWidget *widget,
182                                                  GdkEventExpose *event)
183 {
184
185     HildonVolumebarPrivate *priv;
186
187     priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
188     g_assert (priv);
189
190     if (GTK_WIDGET_DRAWABLE (widget)) {
191         /* Paint background */
192         gtk_paint_box (widget->style, widget->window,
193                 GTK_WIDGET_STATE (priv->volumebar), GTK_SHADOW_OUT,
194                 NULL, widget, "background",
195                 widget->allocation.x,
196                 widget->allocation.y,
197                 widget->allocation.width,
198                 widget->allocation.height);
199
200         /* The contents of the widget can paint themselves */
201         (*GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
202     }
203
204     return FALSE;
205 }
206
207 static void
208 hildon_vvolumebar_size_request                  (GtkWidget *widget,
209                                                  GtkRequisition *requisition)
210 {
211     requisition->height = MINIMUM_BAR_HEIGHT;
212     requisition->width = DEFAULT_BAR_WIDTH;
213 }
214
215 static void
216 hildon_vvolumebar_size_allocate                 (GtkWidget *widget,
217                                                  GtkAllocation *allocation)
218 {
219     HildonVolumebarPrivate *priv;
220
221     GtkAllocation range_allocation, button_allocation;
222
223     priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
224     g_assert (priv);
225
226     /* Center the widget horizontally */
227     if (allocation->width > DEFAULT_BAR_WIDTH) {
228         allocation->x +=
229             (allocation->width - DEFAULT_BAR_WIDTH) / 2;
230         allocation->width = DEFAULT_BAR_WIDTH;
231     }
232
233     GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
234
235     if (priv->volumebar && GTK_WIDGET_VISIBLE (priv->volumebar)) {
236         /* Allocate space for the slider */
237         range_allocation.x = allocation->x;
238         range_allocation.y = allocation->y + DEFAULT_ENDING_SIZE;
239
240         range_allocation.width = DEFAULT_BAR_WIDTH;
241
242         if (priv->tbutton && GTK_WIDGET_VISIBLE (priv->tbutton))
243         {
244             /* Leave room for the mute button */
245             range_allocation.height = MAX (0,
246                     allocation->height
247                     - 2 * DEFAULT_ENDING_SIZE
248                     - DEFAULT_VERTICAL_TBUTTON_HEIGHT
249                     - VERTICAL_MUTE_GAP);
250         }
251
252         else
253         {
254             range_allocation.height = MAX (0,
255                     allocation->height
256                     - 2 * DEFAULT_ENDING_SIZE);
257         }
258
259         gtk_widget_size_allocate (GTK_WIDGET (priv->volumebar),
260                 &range_allocation);
261     }
262
263     if (priv->tbutton && GTK_WIDGET_VISIBLE (priv->tbutton)) {
264         /* Allocate space for the mute button */
265         button_allocation.x = allocation->x + HORIZONTAL_MUTE_GAP;
266         button_allocation.y = allocation->y + allocation->height -
267             VERTICAL_MUTE_GAP - 2 * DEFAULT_ENDING_SIZE;
268         button_allocation.width = DEFAULT_VERTICAL_TBUTTON_WIDTH;
269         button_allocation.height = DEFAULT_VERTICAL_TBUTTON_HEIGHT;
270         gtk_widget_size_allocate (GTK_WIDGET (priv->tbutton),
271                 &button_allocation);
272     }
273 }