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